mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 13:08:07 -06:00
Expressions: follow Media Replacement source dimensions (#1747)
LayerInfo, sourceRectAtTime and Layer.source now resolve the effective footage item/size through the collapsed instance EvalCtx, matching the rendered pixels. Adds a regression test with different original and replacement footage sizes.
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
use effectcraft_geom::{Mat3, Mat4};
|
||||
use effectcraft_keyframe::Value;
|
||||
use effectcraft_project::{Comp, ItemId, ItemKind, Layer, LayerId, LayerSource, Node, PropGroup, Property};
|
||||
use effectcraft_render::{EvalCtx, source_size};
|
||||
use effectcraft_render::EvalCtx;
|
||||
use effectcraft_time::Tick;
|
||||
|
||||
/// A name-or-index argument (`layer("A")`, `layer(2)`, `effect(1)`).
|
||||
@@ -382,7 +382,7 @@ impl<'a> Resolver<'a> {
|
||||
Req::LayerInfo { comp, layer } => {
|
||||
let c = self.comp(*comp)?;
|
||||
let l = self.layer(*comp, *layer)?;
|
||||
let (mut w, mut h) = source_size(project, l);
|
||||
let (mut w, mut h) = self.ctx_at(*comp, self.ctx.time.seconds())?.source_size(l);
|
||||
if w == 0 || h == 0 {
|
||||
(w, h) = (c.width, c.height);
|
||||
}
|
||||
@@ -477,7 +477,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let (w, h) = source_size(project, l);
|
||||
let (w, h) = ctx.source_size(l);
|
||||
[0.0, 0.0, w as f64, h as f64]
|
||||
}
|
||||
};
|
||||
@@ -511,7 +511,12 @@ impl<'a> Resolver<'a> {
|
||||
Req::SourceInfo { comp, layer } => {
|
||||
let c = self.comp(*comp)?;
|
||||
let l = self.layer(*comp, *layer)?;
|
||||
let it = project.item(l.source.item()?)?;
|
||||
let ctx = self.ctx_at(*comp, self.ctx.time.seconds())?;
|
||||
let item = match &l.source {
|
||||
LayerSource::Footage { item } => ctx.media_item(l, *item),
|
||||
_ => l.source.item()?,
|
||||
};
|
||||
let it = project.item(item)?;
|
||||
let (kind, aspect, frame, duration) = match &it.kind {
|
||||
ItemKind::Comp(nc) => ("comp", nc.pixel_aspect, nc.frame_duration().seconds(), nc.duration.seconds()),
|
||||
ItemKind::Footage(f) => ("footage", f.pixel_aspect, f.frame_rate.frame_duration().seconds(), f.duration.seconds()),
|
||||
|
||||
@@ -907,6 +907,49 @@ fn source_rect_at_time() {
|
||||
assert!((s[0] + 31.0).abs() < 2.0 && (s[1] + 16.0).abs() < 2.0 && (s[2] - 62.0).abs() < 3.0, "{s:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn source_dimensions_follow_media_replacement() {
|
||||
let mut p = Project::default();
|
||||
let comp = Comp::new(200, 100, FrameRate::FPS_30, Tick::from_seconds_f64(2.0));
|
||||
let cid = p.add_item("Main", Label::Sandstone, None, ItemKind::Comp(comp.clone().into()));
|
||||
let footage = |p: &mut Project, name: &str, width, height| {
|
||||
p.add_item(
|
||||
name,
|
||||
Label::SeaFoam,
|
||||
None,
|
||||
ItemKind::Footage(effectcraft_project::Footage {
|
||||
path: name.into(),
|
||||
kind: effectcraft_project::FootageKind::Still,
|
||||
width,
|
||||
height,
|
||||
has_video: true,
|
||||
..Default::default()
|
||||
}),
|
||||
)
|
||||
};
|
||||
let original = footage(&mut p, "original.png", 100, 80);
|
||||
let replacement = footage(&mut p, "replacement.png", 30, 40);
|
||||
let mut l = build::layer(&mut p, &comp, "Clip", LayerSource::Footage { item: original }, (100, 80), None);
|
||||
l.props.prop_mut(ROT).unwrap().expr =
|
||||
Some(Expression { text: "thisLayer.width + thisLayer.height + thisLayer.source.width + sourceRectAtTime().width".into(), enabled: true });
|
||||
let lid = l.id;
|
||||
p.comp_mut(cid).unwrap().layers.push(l);
|
||||
let c = p.comp(cid).unwrap();
|
||||
let l = c.layer(lid).unwrap();
|
||||
let media = effectcraft_render::MediaOverride::new(lid, replacement);
|
||||
let ctx = EvalCtx {
|
||||
project: &p,
|
||||
comp_id: cid,
|
||||
comp: c,
|
||||
time: Tick::ZERO,
|
||||
expr: Some(&Expressions),
|
||||
footage: None,
|
||||
property_overrides: &[],
|
||||
media_overrides: &[media],
|
||||
};
|
||||
assert_eq!(ctx.value(l, l.props.prop(ROT).unwrap()), Value::Scalar(130.0));
|
||||
}
|
||||
|
||||
// ---- colour -----------------------------------------------------------------------------------
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user