Skip to content

Stabilize PACS convex-corner sliding for static and border contacts#770

Draft
Copilot wants to merge 6 commits intocore4from
copilot/fix-pacs-stuttering-issue
Draft

Stabilize PACS convex-corner sliding for static and border contacts#770
Copilot wants to merge 6 commits intocore4from
copilot/fix-pacs-stuttering-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 13, 2026

PACS movement could stutter when sliding along convex border corners, while concave corners remained smooth. This was caused by unstable normal-axis corrections during corner-adjacent contacts and by overly aggressive static collision time backoff on tangential outer-edge glancing.

  • Collision-response stability update (PACS)

    • In CPrimitiveWorldImage::reaction(...), clamp remaining collision time used in response math:
      • safeRemainingTime = max(dt - contactTime, 1e-6)
    • This avoids pathological impulse magnitudes near end-of-step contacts.
  • Slide behavior correction at corner contacts

    • For Slide reactions, apply distance-back normal push only when velocity is directed into the contact normal (speedProj < 0).
    • If already moving tangentially / away from the surface normal, do not add extra normal push-back.
    • This reduces oscillation between adjacent convex-edge contacts.
  • Static collision scheduling correction (placed landscape objects / outer edges)

    • In CMoveContainer::newCollision(...) (static surface path), collision-time backoff is no longer based on total speed magnitude for all contacts.
    • Backoff is now applied only when movement is inward along the contact normal, using:
      • inwardVelocity = -(ContactNormal · Speed)
      • thresholded by NELPACS_COLLISION_TIME_EPSILON
    • This prevents unnecessary time rewinds on tangential/glancing outer-edge contacts that can re-trigger near-immediate re-collisions and visible stutter.
  • Scope

    • Localized changes in:
      • nel/src/pacs/primitive_world_image.cpp
      • nel/src/pacs/move_container.cpp
    • No API/protocol/data-format changes.
const double collisionTimeEpsilon = 1e-6;
const double safeRemainingTime = std::max(dt - surfaceDesc.ContactTime, collisionTimeEpsilon);

double speedProj = surfaceDesc.ContactNormal * _Speed;
double distBackVelocity = speedProj < 0.0 ? NELPACS_DIST_BACK / safeRemainingTime : 0.0;
_Speed -= surfaceDesc.ContactNormal * (speedProj - distBackVelocity);
#define NELPACS_COLLISION_TIME_EPSILON 1e-6

const double inwardVelocity = -(desc.ContactNormal * wI->getSpeed());
if (inwardVelocity > NELPACS_COLLISION_TIME_EPSILON)
    time -= NELPACS_DIST_BACK / inwardVelocity;
Original prompt

This section details on the original issue you should resolve

<issue_title>PACS gets stuck when sliding around convex corners</issue_title>
<issue_description>When running against a PACS border, the character stutters around convex corners. Concave corners are smooth.</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 13, 2026 21:13
Co-authored-by: kaetemi <1581053+kaetemi@users.noreply.github.com>
Co-authored-by: kaetemi <1581053+kaetemi@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix PACS stuttering around convex corners Stabilize PACS slide response at convex corners Feb 13, 2026
Copilot AI requested a review from kaetemi February 13, 2026 21:21
@kaetemi
Copy link
Copy Markdown
Member

kaetemi commented Feb 13, 2026

@copilot Can you give a primer/walkthrough on why the original implementation had this behavior, and how your adjustment actually fixes this?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 13, 2026

@copilot Can you give a primer/walkthrough on why the original implementation had this behavior, and how your adjustment actually fixes this?

In the original code, slide always injected a normal “push-back” term (NELPACS_DIST_BACK/(dt-contactTime)) even when the primitive was already moving tangentially or slightly away from that normal. At convex corners, you can hit adjacent borders in rapid succession with changing normals, so that unconditional normal injection keeps reintroducing alternating normal velocity components, which looks like stutter/jitter.

In c13b09c, the slide branch now computes the normal projection first and only applies that push-back when speedProj < 0 (actually moving into the surface normal). If motion is tangential/away, no extra normal velocity is injected. That removes the corner-to-corner normal oscillation while preserving penetration prevention when moving into a wall.

The same commit also clamps remaining time with an epsilon (safeRemainingTime) so near-end-of-step contacts don’t create extreme impulses from division by a tiny value.

@kaetemi
Copy link
Copy Markdown
Member

kaetemi commented Feb 14, 2026

@copilot I tried this and it does not fix the issue. For clarity, this occurs when running/sliding against objects (buildings, etc) that are placed in the landscape. Particularly, the outer edge.

Copilot AI and others added 2 commits February 14, 2026 00:19
Co-authored-by: kaetemi <1581053+kaetemi@users.noreply.github.com>
Co-authored-by: kaetemi <1581053+kaetemi@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 14, 2026

@copilot I tried this and it does not fix the issue. For clarity, this occurs when running/sliding against objects (buildings, etc) that are placed in the landscape. Particularly, the outer edge.

I’ve added a follow-up specifically on the static/landscape collision path used by placed objects in 938f61d.

The static collision scheduling in CMoveContainer::newCollision(...) used to always rewind collision time by NELPACS_DIST_BACK / |speed|, which also affects tangential/glancing contacts at outer convex edges. That can re-queue near-immediate re-collisions and produce the stutter you described.

It now only applies that time backoff when movement is actually inward along the contact normal (with a small epsilon), so tangential edge sliding no longer gets unnecessary time rewinds.

Copilot AI changed the title Stabilize PACS slide response at convex corners Stabilize PACS convex-corner sliding for static and border contacts Feb 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

PACS gets stuck when sliding around convex corners

2 participants