Skip to content

Swept-AABB broadphase for the SDF collision sequence error function#1527

Open
cdtwigg wants to merge 2 commits into
mainfrom
export-D108807344
Open

Swept-AABB broadphase for the SDF collision sequence error function#1527
cdtwigg wants to merge 2 commits into
mainfrom
export-D108807344

Conversation

@cdtwigg

@cdtwigg cdtwigg commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary:
Add a conservative broadphase to SDFCollisionSequenceErrorFunctionT that skips any (vertex, collider) pair whose swept segment cannot reach the collider. The segment is already mapped into the collider's local SDF frame for the sweep; if the segment's local axis-aligned bounding box does not overlap the collider's SDF bounds(), the pair cannot penetrate and is skipped before the more expensive sphere-trace and deepest-point search. Because both the cull and the detailed test operate in the same local frame, the cull is exact — it only ever skips pairs whose detailed test would have found no penetration — so the error, gradient, and Jacobian are unchanged.

This replaces running the sphere-trace for every (vertex, collider) pair regardless of proximity, which matters once the participating-vertex set or collider count is large. It adds bounds() to the (already duck-typed) collider interface this function relies on.

Reviewed By: yutingye

Differential Revision: D108807344

cdtwigg added 2 commits June 17, 2026 07:55
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
Summary:
Add a conservative broadphase to `SDFCollisionSequenceErrorFunctionT` that skips any (vertex, collider) pair whose swept segment cannot reach the collider. The segment is already mapped into the collider's local SDF frame for the sweep; if the segment's local axis-aligned bounding box does not overlap the collider's SDF `bounds()`, the pair cannot penetrate and is skipped before the more expensive sphere-trace and deepest-point search. Because both the cull and the detailed test operate in the same local frame, the cull is exact — it only ever skips pairs whose detailed test would have found no penetration — so the error, gradient, and Jacobian are unchanged.

This replaces running the sphere-trace for every (vertex, collider) pair regardless of proximity, which matters once the participating-vertex set or collider count is large. It adds `bounds()` to the (already duck-typed) collider interface this function relies on.

Reviewed By: yutingye

Differential Revision: D108807344
@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 D108807344.

meta-codesync Bot pushed a commit that referenced this pull request Jun 17, 2026
…1527)

Summary:

Add a conservative broadphase to `SDFCollisionSequenceErrorFunctionT` that skips any (vertex, collider) pair whose swept segment cannot reach the collider. The segment is already mapped into the collider's local SDF frame for the sweep; if the segment's local axis-aligned bounding box does not overlap the collider's SDF `bounds()`, the pair cannot penetrate and is skipped before the more expensive sphere-trace and deepest-point search. Because both the cull and the detailed test operate in the same local frame, the cull is exact — it only ever skips pairs whose detailed test would have found no penetration — so the error, gradient, and Jacobian are unchanged.

This replaces running the sphere-trace for every (vertex, collider) pair regardless of proximity, which matters once the participating-vertex set or collider count is large. It adds `bounds()` to the (already duck-typed) collider interface this function relies on.

Reviewed By: yutingye

Differential Revision: D108807344
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