linebender / interpoli

Apache License 2.0
14 stars 4 forks source link

SMPTE Timecodes & Timelines, Sequences and Keyframes. #22

Open TheNachoBIT opened 1 month ago

TheNachoBIT commented 1 month ago

I'm making this a draft for now, this PR is to document the progress i've been making so far with this experiment.

This experiment can also fail. If you see any kind of flaw, please feel free to point it out.

The final goals of this (if succeeds) are:

Progress.

SMPTE Timecodes (Update 2).

SMPTE Timecodes are time units that are set like a clock: HH:MM:SS:FF (Hours, Minutes, Seconds, Frames).

For convenience, there's a macro that helps visualize this concept better in code:

tcode_hmsf!(01:23:45:01) // A timecode with Hours (h), Minutes (m), Seconds (s) and Frames (f).

~(Sadly, Rust's macros don't allow me to use ":" so i have to use ";" instead, if there's a workaround for this, please let me know)~

EDIT: I fixed it!

Timecodes can be used as a Timestamp, or as a value for a Timeline, by setting the Framerate:

tcode_hmsf_framerate!(00:01:02:56, Framerate::Fixed(20.0))

There's Framerate::Fixed(n) and Framerate::Interpolated(n). Once Timelines become a thing, fixed framerates will round up to the nearest frame when the tween is calculated, which will be useful for frame-by-frame animations. Interpolated frames on the other hand, will interpolate regardless of the framerate you're running (unless you explicitly set "hold" frames).

Timecodes with a framerate can advance and reverse by frames, seconds, minutes, hours and use Duration (Instant coming soon).

Example: Play one second frame-by-frame.

let mut time = tcode_hmsf_framerate!(00:00:00:00, Framerate::Fixed(24.0));

for i in 0..24 {
    time.next_frame();
}

println!("{:?}", time.as_string()); // Outputs "00:00:01:00 (24.0)"

Example: Add by Duration.

use std::time::Duration;

let mut time = tcode_hmsf_framerate!(00:00:00:00, Framerate::Fixed(24.0));

time.add_by_duration(Duration::from_millis(999));

println!("{:?}", time.as_string()); // Outputs "00:00:00:23 (24.0)"

Example: Sub by Duration.

use std::time::Duration;

let mut time = tcode_hmsf_framerate!(01:00:00:00, Framerate::Fixed(24.0)); // 1 hour

time.sub_by_duration(Duration::from_secs(1800));

println!("{:?}", time.as_string()); // Outputs "00:30:00:00 (24.0)" (30 minutes)

The draft repository contains more examples in form of tests inside of lib.rs.

This is all of the progress for now, for any questions, please feel free to ask :)