0) IMPORTANT: RLVa REQUIRED

All FOV features in HS DollyCam require a viewer with RLVa support enabled.
Firestorm: Preferences → Firestorm → RLVa → “Enable RLVa”
If RLVa is OFF, the camera can still move, but FOV commands will do nothing.

HS DollyCam sets FOV via RLVa command:
  @setcam_fov:<radians>=force

Notes:
- This is viewer-side. The HUD sends commands via owner chat.
- Some viewers show “executes: @setcam_fov:...” in chat even when scripts send “quiet”.
  That display is a viewer setting and not HUD spam.


1) UNITS: Radians vs Degrees

FOV in HS DollyCam is stored internally in RADIANS.

Useful references:
- 60°  = 1.04719755 rad
- 45°  = 0.78539816 rad
- 30°  = 0.52359878 rad
- 90°  = 1.57079633 rad

Clamp range (safety):
- Minimum: 10°
- Maximum: 179°


2) STANDALONE FOV COMMANDS (Chat /88)

A) Set FOV in radians
  /88 fov <rad>

Examples:
  /88 fov 1.0472        (≈ 60°)
  /88 fov 0.5236        (≈ 30°)

B) Set FOV in degrees
  /88 fovdeg <deg>

Examples:
  /88 fovdeg 60
  /88 fovdeg 35

C) Convenience heuristic:
If you use /88 fov with a value > 3.2 it is assumed to be degrees.
Example:
  /88 fov 60            (interpreted as 60°, not 60 rad)


3) FOV IN PLAYLIST NOTECARDS

You can set FOV from a playlist notecard as standalone lines.

Syntax:
  fov <rad> [quiet]
  fovdeg <deg> [quiet]

quiet:
- 1 = quiet (default)
- 0 = show debug output (if enabled) / more visible logs

Examples:
  fovdeg 60
  fovdeg 35 1
  fov 1.0472
  fov 0.7854 1

Tip:
If you run a playlist with a gap_ms, FOV lines follow the same pacing rules.


4) PRESETS: SAVING / STORING FOV

HS DollyCam presets store camera position + focus + rotation + FOV.

- Presets are saved in Linkset Data slots “P<idx>”
- v2 preset format includes FOV as the 11th field:
  field index 10 = fovRad

Workflow:
1) Move camera where you want it.
2) Set FOV you want (RLVa required), e.g.:
     /88 fovdeg 35
3) Save the preset:
     /88 save 1

Important:
- The HUD stores the “last set by HUD” FOV as a fallback.
- Best practice: explicitly set FOV, then save, for reliable dollyzoom.


5) APPLYING PRESET FOV (Load / MoveTo)

When you load or moveto a preset, HS DollyCam can apply the preset’s stored FOV.

A) Chat:
  /88 load <idx>          (cut)
  /88 moveto <idx> [ms]   (animated)

B) Menu / Markers:
- Clicking a marker or using the menu load/moveto applies preset FOV if present.

C) Playlists:
- In playlists, moveto/load lines also apply preset FOV (outside tours).

Notes:
- If a preset has no stored FOV, camera movement still works; FOV stays unchanged.


6) TOUR FOV: KEYFRAME RAMP DURING TOURS

Tours are continuous rides through multiple waypoints.
You can optionally ramp FOV during a tour.

A) Tour blocks in notecards:
  tour <total_ms> [mode]
    moveto <idx1> [optional weight tokens]
    moveto <idx2> ...
    fovdeg <degA> <degB>      (optional, can be inside tour block)
    wait <ms>                  (hold at the last waypoint)
  endtour

B) Fast compact tour (chat or notecard):
  /88 tour <ms> [mode] <idx1> <idx2> ... [fovdeg <a> <b>]
  /88 tour <ms> [mode] <idx1> <idx2> ... [fov <radA> <radB>]
  tour <ms> [mode] <idx1> <idx2> ... [fovdeg <a> <b>]
  tour <ms> [mode] <idx1> <idx2> ... [fov <radA> <radB>]

Example:
  /88 tour 8000 spline 1 2 3 4 fovdeg 35 70
  tour 8000 spline 1 2 3 4 fovdeg 35 70

What it does:
- Camera moves along the tour path
- FOV is interpolated from A → B based on path progress (weighted distance)
- FOV ticks are throttled (about 10 Hz) + deduped

Tip:
FOV ramps in tours are a creative tool (stylized “zoom breathing”), not a perfect “dollyzoom”.


7) DOLLYZOOM (Classic)

DollyZoom is a 2-point tour that changes camera distance while counter-changing FOV.

Chat syntax:
  /88 dollyzoom <ms> [mode] <idxA> <idxB>

Chat/menu DollyZoom and one-line tours use HS_CamTourCommands.lsl.

Notecard syntax:
  dollyzoom <ms> [mode] <idxA> <idxB>

Examples:
  /88 dollyzoom 4000 linear 1 2
  /88 dollyzoom 4000 1 2
  dollyzoom 5000 spline 3 4

How it works:
- Builds an internal 2-point TOUR from preset A to preset B
- Uses FOV stored in preset A and preset B:
  FOV ramps from fovA → fovB across the move

Requirements:
- BOTH presets must have FOV stored (unless using “keep”, see below)
- Best results when both presets look at the same subject (same focus point)


8) DOLLYZOOM keep (Keepframe / constant framing)

The current build supports “keepframe” with the “keep” option:

Chat:
  /88 dollyzoom <ms> [mode] <idxA> <idxB> keep

Notecard:
  dollyzoom <ms> [mode] <idxA> <idxB> keep

Goal:
- Keep the apparent size of the subject as constant as possible while moving.

How it works (math):
- Let d(t) = distance between camera position and the “motif focus”
- Define K from the start frame:
    K = d0 * tan(FOV0/2)
- Then compute FOV per tick:
    FOV(t) = 2 * atan( K / d(t) )

What is “motif focus”?
- If LOCK is ON, motif focus comes from the LOCK target (object position + offset).
- If LOCK is OFF, motif focus is fixed to “focA” (focus from the first dolly preset).
- Many setups also force focB = focA automatically for keep to avoid focus drift.

Requirements:
- RLVa ON (for FOV updates)
- A meaningful distance change (camera must move closer/farther to the subject)
- Best when the focus corresponds to the actual subject (not an arbitrary point)

When to use LOCK with keep:
- Use LOCK when the subject moves (avatar walking, vehicle, animated object).
- If the subject is static and focA is correct, you do not need LOCK.

Notes / Limitations (Second Life reality):
- Viewer camera smoothing (Camera Lag/Focus Lag) can make keepframe look “off”
  because the visible camera lags behind the scripted target position.
- FOV updates are throttled and deduped; tiny changes may not be sent every frame.
- Expect “usable” results, not perfect cinema-grade dollyzoom.

Performance note:
- Tour FOV updates are intentionally throttled and deduped.
- Tour camera frame updates are also capped by HS_CamEngine.properties:
    tour_cam_min_interval=0.033
    tour_pos_epsilon=0.005
    tour_focus_epsilon=0.005
- Lower move_step values make the path computation run more often, but they do
  not send camera frames faster than tour_cam_min_interval unless that value is
  lowered too. Lower values increase script load.


9) QUALITY TIPS (Practical)

A) For a strong dollyzoom:
- Make presets with a BIG distance difference (e.g. 3m → 15m)
- Keep focus on the same subject point (focA == focB), or use LOCK
- Use moderate FOV ranges (e.g. 30° → 70°)

B) If it looks “mushy” or delayed:
- Reduce camera lag settings (Engine properties):
  move_pos_lag / move_focus_lag too high will cause visible trailing.
- Consider lowering smoothing for recording, then increase for casual viewing.

C) If dollyzoom looks like “just moving camera”:
- Your distance to focus might not be changing (dA ≈ dB).
- Your focus might be drifting (focA and focB are different, or moving with camera).
- The camera path may be sideways/orbit rather than in/out.


10) TROUBLESHOOTING

Problem: “FOV commands do nothing”
- RLVa is OFF or viewer doesn’t support RLVa.
- Enable RLVa in viewer settings.

Problem: “Chat shows executes: @setcam_fov...”
- That is viewer-side display.
- HUD already uses quiet mode where possible.

Problem: “Dollyzoom says it needs FOV in both presets”
- Set FOV, then save preset A and preset B again:
    /88 fovdeg 35
    /88 save 1
    /88 fovdeg 70
    /88 save 2

Problem: “keep doesn’t feel like dollyzoom”
- Ensure camera distance to motif changes substantially.
- Ensure motif focus is correct (LOCK target or correct focA).
- Lower camera lag (smoothing) if needed.
