mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 05:00:08 +02:00
Pointer: skip unchanged work while the pointer is awake
Every frame (about 116 a second) the helper tested the cursor ray against every visible overlay twice with ComputeOverlayIntersection, set the dot's alpha, width, transform and visibility (five calls into SteamVR), and sent the driver a pose datagram, even with the mouse and the head still. Now a frame reuses the last collision result when the mouse, the anchor (1 mm) and the eye (5 mm) haven't moved and no overlay showed, hid, or changed handle. The passes still run at least every 100 ms, since overlays move on their own (a floating window's controls follow it), and always while dragging. The dots' setters go to SteamVR only when their value changes: the placement when the dot moved 0.2 mm or the eye 5 mm, which turns or resizes it by well under 1%, and the width on a 0.5% change. The plain pose goes to the driver only when the laser's origin moved 0.2 mm or its direction 0.04 deg (0.1 mm where it lands, 15 cm on), and at least every 100 ms; the driver keeps the last pose and reports it every frame. A tilt's pose, a placement, or waking sends the next one regardless. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0680297efa
commit
e1f7ccee29
2 files changed
+186
-103
No files matched your search
+1
-1
@@ -116,7 +116,7 @@ The driver starts disconnected, because holding the right-hand role while SteamV
|
||||
|
||||
### The cursor
|
||||
|
||||
Mouse motion turns into yaw and pitch around an anchor, the head position at the last recenter. A ray from the anchor is tested against every visible overlay with `ComputeOverlayIntersection`. On a hit, the cursor sits on that surface; otherwise it floats at `POINTER_DISTANCE`. Since the anchor isn't your current eye position, a second test runs along your line of sight to the cursor point, and anything nearer wins, so the cursor always lands on what you see under it. Overlays in `POINTER_IGNORE` are left out of both tests. A display-only panel, like a performance overlay locked to your view, has no input method, so SteamVR's laser passes through it, but `ComputeOverlayIntersection` still hits it, and the cursor stuck to it. The laser starts just before the cursor point, so an ignored panel nearer to you doesn't catch it either.
|
||||
Mouse motion turns into yaw and pitch around an anchor, the head position at the last recenter. A ray from the anchor is tested against every visible overlay with `ComputeOverlayIntersection`. On a hit, the cursor sits on that surface; otherwise it floats at `POINTER_DISTANCE`. Since the anchor isn't your current eye position, a second test runs along your line of sight to the cursor point, and anything nearer wins, so the cursor always lands on what you see under it. Overlays in `POINTER_IGNORE` are left out of both tests. A display-only panel, like a performance overlay locked to your view, has no input method, so SteamVR's laser passes through it, but `ComputeOverlayIntersection` still hits it, and the cursor stuck to it. The laser starts just before the cursor point, so an ignored panel nearer to you doesn't catch it either. Both tests ask SteamVR about every visible overlay, so a frame where nothing moved (the mouse, the anchor, the eye by more than 5 mm, which overlays show) reuses the last result, for up to 100 ms, since overlays can also move on their own. The dots' overlay settings go to SteamVR only when they change, and the pose goes to the driver, which keeps the last one, only when the laser would land 0.1 mm or more elsewhere, and at least every 100 ms.
|
||||
|
||||
OpenVR has no call to list other programs' overlays, so the helper runs `vrcmd --overlays` in the background. It includes hidden overlays, because a floating window's controls only appear while something hovers the window, and the cursor has to find them immediately. Each run is a shell and a new SteamVR client, about 30 ms of CPU, and it ran every second while the pointer was awake, which in gaze mode is all the time. Now it runs every 20 seconds, and at once when the pointer wakes, when the dashboard opens or closes, when a game starts or ends, and when a left click hits nothing (a panel that came up since). An overlay already on the list showing or hiding needs no new list: the helper checks the visibility of the ones it knows every 50 ms.
|
||||
|
||||
|
||||
Reference in new issue
Block a user