mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-25 18:47:07 -06:00
Puppet: the first pin no longer turns the layer about it (#313)
With one Position pin and no Bend pins, every rotation and scale about the pin is free in the ARAP energy. The 1e-9 regulariser (about 1e-12 after the edge-length scaling) is too weak to hold them, so the CG solve turned round-off into a visible rotation of several pixels, depending on where the pin landed. The exact solution is the rest mesh translated by the pin's offset, so deform() returns it directly in that case. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d60cb71e29
commit
2cd7a36d66
@@ -186,6 +186,23 @@ fn puppet_pins_deform_and_undo() {
|
||||
assert_eq!(px(&s, 1.0, 100, 25), [0.0, 0.0, 1.0, 1.0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn first_puppet_pin_leaves_the_layer_still() {
|
||||
// #313: an 800×600 solid in a 1920×1080 comp turned about the first pin at these spots.
|
||||
let mut s = Session::default();
|
||||
s.execute("comp.new", json!({"name": "C", "width": 1920, "height": 1080, "duration": 2, "frameRate": 30})).unwrap();
|
||||
let id = s.execute("layer.newSolid", json!({"width": 800, "height": 600, "color": [0, 0, 1]})).unwrap()["layer"].as_u64().unwrap();
|
||||
let cid = s.active_comp_id().unwrap();
|
||||
let before = s.render(cid, Tick::ZERO, RenderOpts::default());
|
||||
for at in [[40, 40], [400, 300], [123, 456]] {
|
||||
s.execute("puppet.addPin", json!({"layer": id, "position": at})).unwrap();
|
||||
let after = s.render(cid, Tick::ZERO, RenderOpts::default());
|
||||
let moved = after.data.iter().zip(&before.data).filter(|(a, b)| (0..4).any(|c| (a[c] - b[c]).abs() > 1e-3)).count();
|
||||
assert_eq!(moved, 0, "pin at {at:?} changed {moved} pixels");
|
||||
s.undo();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn puppet_pin_kinds_and_mesh_options() {
|
||||
let (mut s, id) = setup();
|
||||
|
||||
Reference in New Issue
Block a user