mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-14 19:26:59 -04:00
Roll: reversed clips take the cut from the opposite source end (#526)
This commit is contained in:
1 parent
7bd7621262
commit
0c66f5ffd3
2 files changed
+35
-4
No files matched your search
+17
-4
@@ -751,10 +751,19 @@ pub fn roll(seq: &mut Sequence, left: ClipId, right: ClipId, delta: Tick, ctx: &
|
||||
let mut d = delta;
|
||||
// left out-point limits
|
||||
d = d.max(-(l.duration - ctx.min_duration)).min(r.duration - ctx.min_duration);
|
||||
if let Some(m) = media_len(ctx, l) {
|
||||
// a reversed clip consumes media from the opposite end, so its media limit is the other one
|
||||
if l.reverse {
|
||||
d = d.min(Tick((head(ctx, l).0 as f64 / l.speed.abs()).floor() as i64));
|
||||
} else if let Some(m) = media_len(ctx, l) {
|
||||
d = d.min(Tick(((m - l.source_out()).0 as f64 / l.speed.abs()).floor() as i64));
|
||||
}
|
||||
d = d.max(-Tick((head(ctx, r).0 as f64 / r.speed.abs()).floor() as i64));
|
||||
if r.reverse {
|
||||
if let Some(m) = media_len(ctx, r) {
|
||||
d = d.max(-Tick(((m - r.source_out()).0 as f64 / r.speed.abs()).floor() as i64));
|
||||
}
|
||||
} else {
|
||||
d = d.max(-Tick((head(ctx, r).0 as f64 / r.speed.abs()).floor() as i64));
|
||||
}
|
||||
if d == Tick::ZERO {
|
||||
return Ok(d);
|
||||
}
|
||||
@@ -762,15 +771,19 @@ pub fn roll(seq: &mut Sequence, left: ClipId, right: ClipId, delta: Tick, ctx: &
|
||||
let before = seq.clone();
|
||||
{
|
||||
let (_, l) = seq.find_item_mut(left).ok_or(EditError::NoItem(left))?;
|
||||
if l.reverse {
|
||||
l.source_in -= src_of(d, ls);
|
||||
}
|
||||
l.duration += d;
|
||||
}
|
||||
{
|
||||
let (_, r) = seq.find_item_mut(right).ok_or(EditError::NoItem(right))?;
|
||||
r.start += d;
|
||||
r.duration -= d;
|
||||
r.source_in += src_of(d, rs);
|
||||
if !r.reverse {
|
||||
r.source_in += src_of(d, rs);
|
||||
}
|
||||
}
|
||||
let _ = ls;
|
||||
transitions_follow_cuts(&before, seq);
|
||||
Ok(d)
|
||||
}
|
||||
|
||||
@@ -673,3 +673,21 @@ fn shorter_head_closes_the_stretch_after_the_cut_on_sync_locked_tracks() {
|
||||
assert_eq!(fx.spans(v1), vec![(0, 10), (10, 10), (20, 10)], "unchanged on failure");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn roll_reversed_clips_keeps_media_mapping() {
|
||||
let mut fx = Fx::new();
|
||||
let v = fx.v(0);
|
||||
let mut a = fx.item(0, 30, 20);
|
||||
a.reverse = true;
|
||||
let mut b = fx.item(30, 30, 50);
|
||||
b.reverse = true;
|
||||
let (ia, ib) = (a.id, b.id);
|
||||
fx.seq.track_mut(v).unwrap().items.extend([a, b]);
|
||||
let mut n = 0;
|
||||
roll(&mut fx.seq, ia, ib, f(10), &mut Fx::ctx(&mut n)).unwrap();
|
||||
let (_, l) = fx.seq.find_item(ia).unwrap();
|
||||
assert_eq!((l.start, l.duration, l.source_in), (f(0), f(40), f(10)));
|
||||
let (_, r) = fx.seq.find_item(ib).unwrap();
|
||||
assert_eq!((r.start, r.duration, r.source_in), (f(40), f(20), f(50)));
|
||||
}
|
||||
Reference in new issue
Block a user