1
0
Fork 0
forked from wry/wry

Handle phased animation retargeting

This commit is contained in:
atagen 2026-05-22 16:35:44 +10:00
parent 1a75f47709
commit b211b53528
4 changed files with 263 additions and 7 deletions

View file

@ -402,6 +402,52 @@ pub fn plan_no_overlap_explained(
}
}
pub(crate) fn validate_phase_paths(
request: &MultiphaseRequest,
paths: &[Vec<(Rect, Rect)>],
) -> Result<MultiphasePlan, MultiphasePlanFailure> {
if paths.len() != request.windows.len() {
return Err(MultiphasePlanFailure::NoPattern);
}
let phase_count = paths.iter().map(Vec::len).max().unwrap_or(0);
if phase_count == 0 {
return Err(MultiphasePlanFailure::NoPattern);
}
let mut phases = vec![];
for phase_idx in 0..phase_count {
let mut steps = vec![];
let mut actions = vec![];
for (window_idx, path) in paths.iter().enumerate() {
let Some((from, to)) = path.get(phase_idx).copied() else {
continue;
};
if from == to {
continue;
}
let step = MultiphaseStep {
node_id: request.windows[window_idx].node_id,
from,
to,
};
let Some(action) = classify_step(step) else {
return Err(MultiphasePlanFailure::NoPattern);
};
steps.push(step);
actions.push(action);
}
if !steps.is_empty() {
phases.push(MultiphasePhase {
action: MultiphasePhaseAction::from_step_actions(actions),
steps,
});
}
}
let plan = MultiphasePlan { phases };
validate_plan_continuous_diagnostic(request, &plan)
.map(|_| plan)
.map_err(MultiphasePlanFailure::Validation)
}
pub(crate) fn partition_motion_groups(windows: &[MultiphaseWindow]) -> Vec<Vec<usize>> {
let mut groups = vec![];
let mut seen = vec![false; windows.len()];
@ -2378,6 +2424,42 @@ mod tests {
assert!(validate_plan_continuous(&req, plan));
}
#[test]
fn validated_phase_paths_accept_interrupted_reverse_route() {
let a_current = rect(50, 0, 150, 50);
let b_current = rect(50, 50, 150, 100);
let req = request(vec![
window(1, a_current, rect(0, 0, 100, 100)),
window(2, b_current, rect(100, 0, 200, 100)),
]);
let paths = vec![
vec![
(a_current, rect(0, 0, 100, 50)),
(rect(0, 0, 100, 50), rect(0, 0, 100, 100)),
],
vec![
(b_current, rect(100, 50, 200, 100)),
(rect(100, 50, 200, 100), rect(100, 0, 200, 100)),
],
];
let plan = validate_phase_paths(&req, &paths).unwrap();
assert_eq!(
actions(&plan),
vec![
PhaseAction {
kind: PhaseKind::Move,
axis: PhaseAxis::Horizontal,
},
PhaseAction {
kind: PhaseKind::Scale,
axis: PhaseAxis::Vertical,
},
]
);
assert!(validate_plan_continuous(&req, &plan));
}
#[test]
fn bounded_generated_supported_split_tree_corpus_is_deterministic() {
let mut cases = vec![];