mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 15:48:33 +00:00
1010: preserve easing while baking parented Orientation
This commit is contained in:
1 parent
7e6d76406b
commit
f64cd5ce38
2 files changed
+30
-1
No files matched your search
@@ -818,7 +818,15 @@ fn bake_between(
|
||||
let tm = Tick(ta.0 + (tb.0 - ta.0) / 2);
|
||||
let blend = [(ea[0] + eb[0]) / 2.0, (ea[1] + eb[1]) / 2.0, (ea[2] + eb[2]) / 2.0];
|
||||
let exact = correction * Mat4::orientation(Vec3::from(authored.value_at(tm).as_vec3()));
|
||||
if rotation_angle(Mat4::orientation(Vec3::from(blend)), exact) <= BAKE_TOLERANCE_DEGREES {
|
||||
// Symmetric easing crosses the straight blend at its midpoint. Check both sides too before
|
||||
// accepting a segment whose original easing will be replaced with a linear blend.
|
||||
let quarter = (tb.0 - ta.0) / 4;
|
||||
if [Tick(ta.0 + quarter), tm, Tick(tb.0 - quarter)].into_iter().all(|t| {
|
||||
let u = (t.0 - ta.0) as f64 / (tb.0 - ta.0) as f64;
|
||||
let linear = std::array::from_fn(|i| ea[i] + (eb[i] - ea[i]) * u);
|
||||
let target = correction * Mat4::orientation(Vec3::from(authored.value_at(t).as_vec3()));
|
||||
rotation_angle(Mat4::orientation(Vec3::from(linear)), target) <= BAKE_TOLERANCE_DEGREES
|
||||
}) {
|
||||
return;
|
||||
}
|
||||
let em = nearest_euler(euler_zyx(exact.0), blend);
|
||||
|
||||
@@ -325,6 +325,27 @@ fn keyed_orientation_under_a_tilted_null_follows_between_the_keys() {
|
||||
|
||||
// ---------------------------------------------------------------- from 3D model
|
||||
|
||||
/// Easy Ease agrees with a straight blend at the midpoint, but not at the quarter points.
|
||||
#[test]
|
||||
fn eased_orientation_under_x_parent_keeps_motion_between_keys() {
|
||||
let mut s = session();
|
||||
let light = s.execute("layer.newLight", json!({"kind": "Point", "position": [320, 180, -500]})).unwrap()["layer"].as_u64().unwrap();
|
||||
for (time, value) in [(0.0, json!([0.0, 0.0, 0.0])), (1.0, json!([90.0, 0.0, 0.0]))] {
|
||||
s.execute("prop.addKey", json!({"layer": light, "path": "transform/orientation", "time": time, "value": value})).unwrap();
|
||||
}
|
||||
let uid = layer_in(&s, cid(&s), light).props.prop("transform/orientation").unwrap().uid;
|
||||
s.execute("keys.select", json!({"keys": [{"layer": light, "prop": uid, "time": 0.0}, {"layer": light, "prop": uid, "time": 1.0}]})).unwrap();
|
||||
s.execute("keys.easyEase", json!({})).unwrap();
|
||||
let times: Vec<_> = (0..=100).map(|i| Tick::from_seconds_f64(i as f64 / 100.0)).collect();
|
||||
let before: Vec<_> = times.iter().map(|t| frame_at(&s, light, *t)).collect();
|
||||
let parent = rotated_null(&mut s, [30.0, 0.0, 0.0], 0.0);
|
||||
s.execute("layer.setParent", json!({"layers": [light], "parent": parent})).unwrap();
|
||||
for (t, b) in times.into_iter().zip(before) {
|
||||
let a = frame_at(&s, light, t);
|
||||
assert!((a.0 - b.0).length() < 1e-6 && (a.1 - b.1).length() < 1e-3, "at {t:?}: {:?} vs {:?}", a.1, b.1);
|
||||
}
|
||||
}
|
||||
|
||||
struct DiskModels;
|
||||
|
||||
impl FootageSource for DiskModels {
|
||||
|
||||
Reference in new issue
Block a user