Skip to content

Add swept SDF collision sequence error function (anti-tunneling) (#1526)#1526

Open
cdtwigg wants to merge 1 commit into
mainfrom
export-D108807348
Open

Add swept SDF collision sequence error function (anti-tunneling) (#1526)#1526
cdtwigg wants to merge 1 commit into
mainfrom
export-D108807348

Conversation

@cdtwigg

@cdtwigg cdtwigg commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary:

Add SDFCollisionSequenceErrorFunctionT, a two-frame SequenceErrorFunctionT that penalizes a vertex sweeping through an SDF collider between consecutive frames. The single-frame SDFCollisionErrorFunctionT only sees penetration at the sampled poses, so a vertex moving fast enough to pass entirely through a thin collider (a finger, say) in one timestep is never penalized — it tunnels. This closes that gap for the sequence solver, which is used to post-process existing motion.

How it works:

  • For each participating vertex, the segment connecting its position at frame t and t+1 is swept against each collider in the collider's local SDF frame: each endpoint is mapped through its own frame's world-to-collider transform and the two local positions are interpolated linearly. This captures the relative motion when both vertex and collider are joint-driven, keeps the interpolation exactly differentiable (no slerp-derivative approximation), and makes the sphere-trace that locates surface crossings exactly conservative (distances and steps are in the same local units, so a thin feature can't be stepped over).
  • The penalty is w * phiMax^2 per penetrating sub-interval, where phiMax is the greatest penetration depth reached along the sweep. It is a max, not an integral, so it depends only on how deep the pass-through gets, never on how long the segment stays inside (no degenerate "stretch the trajectory to dilute the penalty" direction). The deepest point is located exactly by bisecting d'(s) = 0; because it is a true interior extremum, the envelope theorem makes the gradient independent of how the deepest point drifts with the parameters, so it reduces to the single-frame contact gradient evaluated there, split across the two frames by the interpolation weights (1 - s*) and s*. One residual per interval; gradient and Jacobian both finite-difference clean.
  • Only sub-intervals bounded by two real surface crossings (entry and exit) are penalized, targeting the pure pass-through case and leaving at-frame penetration to the per-frame error function.
  • Derivatives reuse the shared detail_sdf_collision chain-rule helpers from the previous diff, evaluated against both frames' skeleton states. The local SDF gradient is mapped to world space including the world-to-collider scale factor, which the derivatives require whenever the collider's joint carries a non-unit scale.

The penetration normal is treated as frozen per evaluation (the standard Gauss-Newton contact linearization), so no SDF second derivatives are needed — only transform derivatives, which the shared helpers already provide.

Known limitation / follow-up: a vertex passing exactly through a collider's medial axis (dead-center through the axis of a thin tube, or perpendicular through a thin sheet) lands on a degenerate point where the SDF normal is undefined and the depth has a non-smooth maximum, so the gradient there is ~0 and gives no signal. This is a measure-zero case for convex colliders (any off-axis pass resolves correctly by deflection); a retract-along-the-entry-normal fallback for it is a planned follow-up. There is also no broadphase culling yet (every participating vertex is swept against every collider) and no pymomentum binding (the single-frame function has one).

Reviewed By: yutingye

Differential Revision: D108807348

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jun 17, 2026
@meta-codesync

meta-codesync Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

@cdtwigg has exported this pull request. If you are a Meta employee, you can view the originating Diff in D108807348.

@meta-codesync meta-codesync Bot changed the title Add swept SDF collision sequence error function (anti-tunneling) Add swept SDF collision sequence error function (anti-tunneling) (#1526) Jun 17, 2026
meta-codesync Bot pushed a commit that referenced this pull request Jun 17, 2026
Summary:

Add `SDFCollisionSequenceErrorFunctionT`, a two-frame `SequenceErrorFunctionT` that penalizes a vertex sweeping through an SDF collider between consecutive frames. The single-frame `SDFCollisionErrorFunctionT` only sees penetration at the sampled poses, so a vertex moving fast enough to pass entirely through a thin collider (a finger, say) in one timestep is never penalized — it tunnels. This closes that gap for the sequence solver, which is used to post-process existing motion.

How it works:
- For each participating vertex, the segment connecting its position at frame t and t+1 is swept against each collider in the collider's local SDF frame: each endpoint is mapped through its own frame's world-to-collider transform and the two local positions are interpolated linearly. This captures the relative motion when both vertex and collider are joint-driven, keeps the interpolation exactly differentiable (no slerp-derivative approximation), and makes the sphere-trace that locates surface crossings exactly conservative (distances and steps are in the same local units, so a thin feature can't be stepped over).
- The penalty is `w * phiMax^2` per penetrating sub-interval, where `phiMax` is the greatest penetration depth reached along the sweep. It is a max, not an integral, so it depends only on how deep the pass-through gets, never on how long the segment stays inside (no degenerate "stretch the trajectory to dilute the penalty" direction). The deepest point is located exactly by bisecting `d'(s) = 0`; because it is a true interior extremum, the envelope theorem makes the gradient independent of how the deepest point drifts with the parameters, so it reduces to the single-frame contact gradient evaluated there, split across the two frames by the interpolation weights `(1 - s*)` and `s*`. One residual per interval; gradient and Jacobian both finite-difference clean.
- Only sub-intervals bounded by two real surface crossings (entry and exit) are penalized, targeting the pure pass-through case and leaving at-frame penetration to the per-frame error function.
- Derivatives reuse the shared `detail_sdf_collision` chain-rule helpers from the previous diff, evaluated against both frames' skeleton states. The local SDF gradient is mapped to world space including the world-to-collider scale factor, which the derivatives require whenever the collider's joint carries a non-unit scale.

The penetration normal is treated as frozen per evaluation (the standard Gauss-Newton contact linearization), so no SDF second derivatives are needed — only transform derivatives, which the shared helpers already provide.

Known limitation / follow-up: a vertex passing exactly through a collider's medial axis (dead-center through the axis of a thin tube, or perpendicular through a thin sheet) lands on a degenerate point where the SDF normal is undefined and the depth has a non-smooth maximum, so the gradient there is ~0 and gives no signal. This is a measure-zero case for convex colliders (any off-axis pass resolves correctly by deflection); a retract-along-the-entry-normal fallback for it is a planned follow-up. There is also no broadphase culling yet (every participating vertex is swept against every collider) and no pymomentum binding (the single-frame function has one).

Reviewed By: yutingye

Differential Revision: D108807348
@meta-codesync meta-codesync Bot force-pushed the export-D108807348 branch from e5ae335 to 1316202 Compare June 17, 2026 14:10
Summary:

Add `SDFCollisionSequenceErrorFunctionT`, a two-frame `SequenceErrorFunctionT` that penalizes a vertex sweeping through an SDF collider between consecutive frames. The single-frame `SDFCollisionErrorFunctionT` only sees penetration at the sampled poses, so a vertex moving fast enough to pass entirely through a thin collider (a finger, say) in one timestep is never penalized — it tunnels. This closes that gap for the sequence solver, which is used to post-process existing motion.

How it works:
- For each participating vertex, the segment connecting its position at frame t and t+1 is swept against each collider in the collider's local SDF frame: each endpoint is mapped through its own frame's world-to-collider transform and the two local positions are interpolated linearly. This captures the relative motion when both vertex and collider are joint-driven, keeps the interpolation exactly differentiable (no slerp-derivative approximation), and makes the sphere-trace that locates surface crossings exactly conservative (distances and steps are in the same local units, so a thin feature can't be stepped over).
- The penalty is `w * phiMax^2` per penetrating sub-interval, where `phiMax` is the greatest penetration depth reached along the sweep. It is a max, not an integral, so it depends only on how deep the pass-through gets, never on how long the segment stays inside (no degenerate "stretch the trajectory to dilute the penalty" direction). The deepest point is located exactly by bisecting `d'(s) = 0`; because it is a true interior extremum, the envelope theorem makes the gradient independent of how the deepest point drifts with the parameters, so it reduces to the single-frame contact gradient evaluated there, split across the two frames by the interpolation weights `(1 - s*)` and `s*`. One residual per interval; gradient and Jacobian both finite-difference clean.
- Only sub-intervals bounded by two real surface crossings (entry and exit) are penalized, targeting the pure pass-through case and leaving at-frame penetration to the per-frame error function.
- Derivatives reuse the shared `detail_sdf_collision` chain-rule helpers from the previous diff, evaluated against both frames' skeleton states. The local SDF gradient is mapped to world space including the world-to-collider scale factor, which the derivatives require whenever the collider's joint carries a non-unit scale.

The penetration normal is treated as frozen per evaluation (the standard Gauss-Newton contact linearization), so no SDF second derivatives are needed — only transform derivatives, which the shared helpers already provide.

Known limitation / follow-up: a vertex passing exactly through a collider's medial axis (dead-center through the axis of a thin tube, or perpendicular through a thin sheet) lands on a degenerate point where the SDF normal is undefined and the depth has a non-smooth maximum, so the gradient there is ~0 and gives no signal. This is a measure-zero case for convex colliders (any off-axis pass resolves correctly by deflection); a retract-along-the-entry-normal fallback for it is a planned follow-up. There is also no broadphase culling yet (every participating vertex is swept against every collider) and no pymomentum binding (the single-frame function has one).

Reviewed By: yutingye

Differential Revision: D108807348
@meta-codesync meta-codesync Bot force-pushed the export-D108807348 branch from 1316202 to 8be474e Compare June 17, 2026 14:54
meta-codesync Bot pushed a commit that referenced this pull request Jun 17, 2026
Summary:

Add `SDFCollisionSequenceErrorFunctionT`, a two-frame `SequenceErrorFunctionT` that penalizes a vertex sweeping through an SDF collider between consecutive frames. The single-frame `SDFCollisionErrorFunctionT` only sees penetration at the sampled poses, so a vertex moving fast enough to pass entirely through a thin collider (a finger, say) in one timestep is never penalized — it tunnels. This closes that gap for the sequence solver, which is used to post-process existing motion.

How it works:
- For each participating vertex, the segment connecting its position at frame t and t+1 is swept against each collider in the collider's local SDF frame: each endpoint is mapped through its own frame's world-to-collider transform and the two local positions are interpolated linearly. This captures the relative motion when both vertex and collider are joint-driven, keeps the interpolation exactly differentiable (no slerp-derivative approximation), and makes the sphere-trace that locates surface crossings exactly conservative (distances and steps are in the same local units, so a thin feature can't be stepped over).
- The penalty is `w * phiMax^2` per penetrating sub-interval, where `phiMax` is the greatest penetration depth reached along the sweep. It is a max, not an integral, so it depends only on how deep the pass-through gets, never on how long the segment stays inside (no degenerate "stretch the trajectory to dilute the penalty" direction). The deepest point is located exactly by bisecting `d'(s) = 0`; because it is a true interior extremum, the envelope theorem makes the gradient independent of how the deepest point drifts with the parameters, so it reduces to the single-frame contact gradient evaluated there, split across the two frames by the interpolation weights `(1 - s*)` and `s*`. One residual per interval; gradient and Jacobian both finite-difference clean.
- Only sub-intervals bounded by two real surface crossings (entry and exit) are penalized, targeting the pure pass-through case and leaving at-frame penetration to the per-frame error function.
- Derivatives reuse the shared `detail_sdf_collision` chain-rule helpers from the previous diff, evaluated against both frames' skeleton states. The local SDF gradient is mapped to world space including the world-to-collider scale factor, which the derivatives require whenever the collider's joint carries a non-unit scale.

The penetration normal is treated as frozen per evaluation (the standard Gauss-Newton contact linearization), so no SDF second derivatives are needed — only transform derivatives, which the shared helpers already provide.

Known limitation / follow-up: a vertex passing exactly through a collider's medial axis (dead-center through the axis of a thin tube, or perpendicular through a thin sheet) lands on a degenerate point where the SDF normal is undefined and the depth has a non-smooth maximum, so the gradient there is ~0 and gives no signal. This is a measure-zero case for convex colliders (any off-axis pass resolves correctly by deflection); a retract-along-the-entry-normal fallback for it is a planned follow-up. There is also no broadphase culling yet (every participating vertex is swept against every collider) and no pymomentum binding (the single-frame function has one).

Reviewed By: yutingye

Differential Revision: D108807348
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant