Fix voice camera tilt from a top-down view

A voice fly-to frames a city top-down, at pitch -90. The tilt clamp
rejected any step that left the pitch below -89, so the first frame of
"tilt up" stopped the motion and "tilt down" was refused: from the view
voice lands on, no tilt ever moved the camera. A bare "tilt the camera"
also failed because tilt required a direction.

- Clamp tilt only in the direction of travel, so -90 can tilt up.
- Swing the camera about the ground under the crosshair, so the place
  stays centred and the heading is kept. A tracked view still tilts in
  place, and a pivot tilt yields when tracking takes the camera.
- Add an optional move_camera pitchDeg for "tilt 45 degrees"; a tilt
  with neither angle nor direction settles at -45 (oblique view).
- Re-derive the voice tool schema pins for the new argument and wording,
  and keep the Realtime prompt under its 52,000-character budget.
This commit is contained in:
Manjunath committed 2026-11-03 16:42:18 +05:30
1 parent 0e27d69fcc
commit 69152868e4
9 files changed
+403 -27

No files matched your search

+6 -1
View File
@@ -225,10 +225,15 @@ test('no unchanged Realtime tool definition drifts silently', () => {
camera.description,
'Direct the camera like a drone operator: orbit the current view target, pan, tilt, or rotate — one bounded nudge (mode=once) or continuous motion until stopped (mode=continuous). Continuous motion also stops on any manual camera input or when a navigation tool runs. Say the RESULTING state when confirming ("Orbiting slowly"). Globe rotation (rotate_globe) spins Earth right continuously by default; explicit direction, mode and speed take precedence. It checks fit and may refuse.',
);
// Tilt to an angle adds pitchDeg and says a tilt nudge needs a
// direction; check them, then restore the legacy fields for the pin.
assert.equal(
camera.parameters.properties.direction.description,
'Required for pan/tilt/rotate; orbit/rotate_globe default right.',
'Required for pan/rotate and a tilt nudge; orbit/rotate_globe default right.',
);
assert.equal(camera.parameters.properties.pitchDeg.type, 'number');
assert.match(camera.parameters.properties.pitchDeg.description, /-45 oblique/);
delete camera.parameters.properties.pitchDeg;
assert.equal(camera.parameters.properties.mode.description, 'once = bounded eased nudge; continuous = until stop/manual input. rotate_globe defaults continuous; other motions default once.');
camera.parameters.properties.mode.description = 'once = bounded eased nudge (default); continuous = until stop/manual input.';
camera.parameters.properties.motion.enum =