Skip to content

fix(webclient): fix XR panel snapping to face away from user when dragged to the side#629

Open
yanziz-nvidia wants to merge 1 commit into
mainfrom
fix/webclient-panel-face-away-snap
Open

fix(webclient): fix XR panel snapping to face away from user when dragged to the side#629
yanziz-nvidia wants to merge 1 commit into
mainfrom
fix/webclient-panel-face-away-snap

Conversation

@yanziz-nvidia

@yanziz-nvidia yanziz-nvidia commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Closes #546

Summary

  • Bug 1 (snap fix): The face-camera damp() call had no angle wrapping. The target yaw from setFromQuaternion lives in [-π, +π], so when the camera crosses near the side/behind the panel the target jumps from +π-ε to -π+ε — geometrically ~0° but numerically ~2π. damp() is a plain lerp so it took the ~2π wrong-way path, spinning the panel to face backward. Fix normalizes the diff to [-π, π] before calling damp().
  • Bug 2 (yaw accuracy): The old code used setFromUnitVectors(zAxis, dir3D) + setFromQuaternion('YXZ') to get the horizontal yaw. Because dir3D included the camera's height offset, the 3D shortest-path quaternion's Euler Y was not the true horizontal yaw. Replaced with Math.atan2(dx, dz) on the XZ plane — simpler and correct.

Test plan

  • Enter XR session and drag the panel to the far left or right of your FOV
  • Walk close to the side of the panel so the camera is nearly level with its edge — panel should continue facing you, not snap away
  • Walk behind the panel — it should smoothly rotate to re-face you
  • Verify normal forward-facing behaviour is unchanged

🤖 Generated with Claude Code

…gged to the side

Two bugs in the face-camera rotation logic in CloudXRUI:

1. Missing angle wrapping before damp(): eulerHelper.y lives in [-π, +π].
   When the panel is near the side of the scene the target angle can flip
   from +π-ε to -π+ε — geometrically ~0° but numerically ~2π. damp() is a
   plain lerp so it interpolated the full ~2π the wrong way, spinning the
   panel to face backward. Fix wraps the diff to [-π, π] before calling
   damp() so it always takes the shortest rotation path.

2. 3D quaternion for a yaw-only problem: setFromUnitVectors(zAxis, dir3D)
   computed the shortest-path 3D rotation including height offset, so the
   extracted Euler Y was not the correct horizontal yaw when camera and panel
   heights differed. Replaced with Math.atan2(dx, dz) on the XZ plane which
   gives correct horizontal yaw directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

CloudXRUI.tsx refactors the face-camera rotation implementation to remove quaternion and Euler conversions. The module now imports only essential Three.js types, retains position-vector helpers for computing projected coordinates on the XZ plane, and directly computes target yaw using atan2 from those projections. Angular deltas are normalized to the range [-π, π] for shortest-path interpolation, and the group rotation is dampened toward the computed target, replacing the prior quaternion-to-Euler (YXZ) extraction logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main bug fix: correcting XR panel snapping behavior when dragged to the side, which matches the core objective of fixing face-camera rotation logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/webclient-panel-face-away-snap

Comment @coderabbitai help to get the list of available commands and usage tips.

@yanziz-nvidia yanziz-nvidia marked this pull request as draft June 5, 2026 05:25
@yanziz-nvidia yanziz-nvidia marked this pull request as ready for review June 5, 2026 17:01
@yanziz-nvidia

Copy link
Copy Markdown
Contributor Author

@yanziz-nvidia yanziz-nvidia requested a review from nv-jakob June 5, 2026 18:05

@gareth-morgan-nv gareth-morgan-nv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Maybe add a test?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IsaacTeleop WebXR client thumbsticks move and gets stuck

2 participants