instrument: fix AHD DecayEnd overlay/grab defect, pin flaky curve test, close comment/doc findings
This commit is contained in:
@@ -108,11 +108,29 @@ double curveFromKnotDrag(const StageEnvelope& grabEnv, EnvNode knot, double grab
|
||||
return curveFromMidLevel((newLevel - seg.start) / span);
|
||||
}
|
||||
|
||||
// An AHD's DecayEnd moves decaySeconds via X, scaled by 1/(1 - holdFraction) — see
|
||||
// resolveNodeDrag's DecayEnd case. At holdFraction == 1.0 that derivative is exactly 0, so a
|
||||
// drag there can never change anything; when it ALSO coincides with HoldEnd (decay ~ 0) it is a
|
||||
// dead handle sitting on top of a live one. Excluded from the grabbable set in that exact case
|
||||
// only — a functional DecayEnd (holdFraction < 1) stays grabbable even when it coincides.
|
||||
bool ahdDecayEndIsDead(const StageEnvelope& env, const std::vector<EnvVertex>& poly) {
|
||||
if (env.kind != EnvKind::Ahd) return false;
|
||||
if (1.0 - clamp01(env.holdFraction) > 1e-9) return false;
|
||||
EnvVertex hold, decay;
|
||||
bool haveHold = false, haveDecay = false;
|
||||
for (const EnvVertex& v : poly) {
|
||||
if (v.node == EnvNode::HoldEnd) { hold = v; haveHold = true; }
|
||||
else if (v.node == EnvNode::DecayEnd) { decay = v; haveDecay = true; }
|
||||
}
|
||||
return haveHold && haveDecay && hold.x == decay.x;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NodeHit nodeAtPoint(const StageEnvelope& env, const OverlayArea& area, double totalSeconds,
|
||||
int x, int y) {
|
||||
const std::vector<EnvVertex> poly = buildEnvelopePolyline(env, area, totalSeconds);
|
||||
const bool dropDeadDecayEnd = ahdDecayEndIsDead(env, poly);
|
||||
// Nearest draggable, kind-matching node within the pick radius wins (Chebyshev distance);
|
||||
// ties go to the earlier draw-order node. Knots are appended last, so a knot coincident
|
||||
// with an endpoint handle loses — a drag there stays a time edit.
|
||||
@@ -120,6 +138,7 @@ NodeHit nodeAtPoint(const StageEnvelope& env, const OverlayArea& area, double to
|
||||
int bestDist = kNodeGrabRadius + 1;
|
||||
for (const EnvVertex& v : poly) {
|
||||
if (!isDraggable(v.node) || !nodeInKind(v.node, env.kind)) continue;
|
||||
if (dropDeadDecayEnd && v.node == EnvNode::DecayEnd) continue;
|
||||
const int dist = std::max(std::abs(x - v.x), std::abs(y - v.y));
|
||||
if (dist < bestDist) { // strict-less-than keeps ties at the earlier draw order
|
||||
bestDist = dist;
|
||||
|
||||
Reference in New Issue
Block a user