HS DollyCam HUD - User Manual (v1.3.0)
====================================

1) What this HUD does
---------------------
HS DollyCam is a cinematic camera dolly tool for Second Life.

It lets you:
- Save camera presets (position + focus)
- Move smoothly between presets (moveto) or cut instantly (load)
- Play camera playlists from notecards (one command per line)
- Use TOUR mode for one continuous camera ride across waypoints
- Use FOV presets, FOV ramps and DollyZoom via RLVa-enabled viewers
- Use optional lock/follow modes (secondary, lower priority than moves)
- Visualize presets with clickable marker "pyramids" (optional helper)
- Use the touch menu for common Save / MoveTo / Play / Tour / Follow / Lock workflows

2) Requirements & Permissions
-----------------------------
Camera permissions:
- The HUD requests Camera Control permission (viewer popup).
- It also requests Camera Tracking for better capture/saving accuracy.

FOV / DollyZoom:
- FOV commands require a viewer with RLVa support enabled.
- If RLVa is off, normal camera motion still works, but FOV changes do nothing.

Markers ("show cams"):
- Parcel must allow you to rez objects (or allow attachments to rez).
- Parcel must have enough remaining object capacity / LI.
- Markers will fail on no-rez parcels or if you hit parcel object limits.

3) Setup
--------
1) Wear the HUD.
2) The HUD automatically asks for camera control when it starts while worn.
   You can also enable camera control manually:

   /88 cam on

   Tip (Viewer quirk / SL restriction):
   Sometimes the viewer does not immediately switch into the scripted camera mode,
   especially if you recently moved/rotated the camera manually or a UI element
   has input focus. If the dolly cam feels like it is "not taking over", press
   ESC once (sometimes twice).

   Why this happens:
   This is a Second Life viewer limitation. ESC clears certain viewer-side camera
   and input states (camera manipulation focus, mouselook, modal UI capture).
   The HUD can set camera parameters only when the viewer is ready to accept them,
   so ESC often nudges the viewer back into the correct state.

3) Accept the permission popup.

To release camera control later:

   /88 cam off


4) Quick Start (60 seconds)
---------------------------
1) Move your viewer camera to a nice framing.

   /88 save 1

2) Aim for another framing.

   /88 save 2

3) Smooth cinematic moves:

   /88 moveto 1 2500
   /88 moveto 2 2500

4) Instant cut:

   /88 load 1

5) Chat Commands (/88)
----------------------

A) Help
   /88 help
   Shows a quick cheat sheet.

B) Camera
   /88 cam on
   Requests permission and activates dolly camera.

   /88 cam off
   Releases camera and clears camera params.

C) Presets (Linkset Data)
   /88 save <idx>
   Saves current camera position + focus to preset slot <idx>.

   /88 load <idx>
   Instant cut to preset <idx> (no smoothing).

   /88 moveto <idx> [duration_ms]
   Smooth move to preset <idx> over duration_ms.
   If duration_ms is omitted, default_move_ms is used.

   /88 del <idx>
   Deletes preset <idx>.

   /88 list [from] [count]
   Lists saved presets in a range.

   Important:
   - preset index must be > 0 (slot 0 is reserved).

D) Playlist
   /88 play <notecard> [gap_ms]
   Plays a playlist notecard (one command per line).
   gap_ms adds a delay after each action (default 0).

   /88 stop
   Stops playlist and stops the current move.

E) Config
   /88 cfg reload
   Reload engine config from HS_CamEngine.properties.

   /88 cfg dump
   Prints current engine config values.

F) Markers (requires HS_CamMarkers helper)
   /88 show cams [N]
   Rezzes up to N clickable markers for saved presets.

   /88 hide cams
   Cleans up all markers created by the HUD.

G) Secondary modes (lower priority than MoveTo / Tour)
   LOCK (focus only):
     /88 lock on [<x,y,z>|uuid]
     /88 lock off

   FOLLOW (capture follow):
     /88 follow on [uuid] [yaw|local|world] [transition_ms]
     /88 follow off

H) FOV / DollyZoom (requires RLVa)
   Note: one-line /88 tour, /88 dollyzoom and menu Tour Builder use
   HS_CamTourCommands.lsl.

   /88 fov <rad>
   Sets viewer FOV in radians. Values greater than 3.2 are treated as degrees.

   /88 fovdeg <deg>
   Sets viewer FOV in degrees. Range is clamped to 10..179.

   /88 tour <ms> [mode] <idx1> <idx2> ... [fovdeg <a> <b>|fov <radA> <radB>]
   Runs a one-line tour and optionally ramps FOV from a to b.

   /88 dollyzoom <ms> [mode] <idxA> <idxB> [keep]
   Runs a 2-point tour using stored FOV from the presets. "keep" computes
   FOV from camera distance to keep framing more stable.

   Tip:
   For reliable DollyZoom results, set FOV explicitly before saving both
   presets, e.g. "/88 fovdeg 35" then "/88 save 1", then set the second
   FOV and "/88 save 2".

I) Touch menu
   Touch the HUD to open the menu.
   The menu supports Save, MoveTo/Cut, Play, Tour Builder, Settings,
   Follow/Lock target picking, Show/Hide Cams and Stop.

   Notes:
   - The menu shows preset slots 1..30.
   - The Play menu shows only notecards whose names start with "shot_".
   - Chat /88 play can still play any notecard name you provide.

6) Playlist Notecard Format
---------------------------
Create a notecard, put it into the HUD contents, then:

   /88 play MyPlaylist 250

The playlist reader uses the simulator notecard cache when available, with an
automatic fallback to normal dataserver reads.

Rules:
- One command per line (NO "/88" prefix in notecards).
- Empty lines and comments are allowed:
  # comment
  // comment
  ; comment
- Tokens are split by spaces. (The playlist parser does NOT re-join vectors that contain spaces.)

Supported playlist commands (core):
- moveto <idx> [ms]
- goto <idx> [ms]          (alias of moveto)
- load <idx> [ms]          (default is cut; if [ms] is provided it will be used)
- wait <ms>
- fov <rad> [quiet]
- fovdeg <deg> [quiet]
- dollyzoom <ms> [mode] <idxA> <idxB> [keep]
- lock on|off [arg]
- follow on|off [target] [modeInt] [transition_ms]
- tour ... / endtour
- show cams [N] / hide cams

Basic example:
  # My cinematic playlist
  moveto 1 2500
  wait 300
  moveto 2 2200
  wait 150
  load 3
  moveto 4 3000

Notes / pitfalls (playlist):
- "load <idx>" is a cut by default, but "load <idx> <ms>" will move smoothly (same as moveto with that duration).
- For lock vectors in notecards, write vectors without spaces, e.g. <128,128,30>.
  (Vectors with spaces like <128, 128, 30> are NOT supported in playlists.)
- For follow in notecards, mode is an integer: 0=yaw, 1=local, 2=world.
  Words like "yaw/local/world" are not parsed as words in playlists.
- For weighted tours, waypoint lines can include weight tokens such as
  "w=1.5" or speed tokens such as "speed=2.0".
- Notecard tour blocks are the primary optimized workflow. Internally the HUD
  stores only preset indices while reading the block, then loads position/focus
  data at endtour.

7) Playlist Timing: MOVE_DONE chaining + "early cut"
----------------------------------------------------
Normal behavior:
- After a move command (moveto/goto/load), the playlist normally continues when the engine signals MOVE_DONE.

Early cut rule (timing):
- If the NEXT actionable line (ignoring empty/comment lines) after a move command is:

     wait <ms>

  ...the playlist will "early cut":
  - it starts that wait immediately,
  - then continues after the wait ends,
  - even if the move has not fully finished.

Notes:
- Early cut applies after moveto, goto, and load.
- Early cut is automatically DISABLED for Tours (a Tour is one continuous move).
- gap_ms (from "/88 play <card> [gap_ms]") is applied after MOVE_DONE; if early cut is used,
  the playlist no longer waits for MOVE_DONE, so the gap may not be applied.

8) TOUR Mode (continuous camera ride)
-------------------------------------
Why Tour exists:
- Back-to-back moveto segments each ease in/out.
  That can feel like: speed up -> slow down -> speed up -> slow down.

Tour runs ONE continuous move:
- One acceleration at the start,
- Constant motion through intermediate waypoints,
- One deceleration at the end.

Syntax:
  tour <total_ms> [mode]
  ... waypoint commands ...
  endtour

Fast compact notecard syntax:
  tour <total_ms> [mode] <idx1> <idx2> ... [fovdeg <a> <b>|fov <radA> <radB>]

- mode defaults to "linear"
- supported mode strings (engine):
  linear / line
  spline
  constant / noease
  ease_in, ease_out, ease_in_out
  smoothstep, cubic, quint
  You can combine spline + profile using "+", e.g. "spline+ease_in_out".
  Use "spline+noease" when a long tour must visibly start immediately.


Inside a tour block:
- moveto <idx> [ms]  -> adds waypoint (ms ignored inside tour)
- goto <idx>         -> same as moveto
- load <idx>         -> adds waypoint (still part of tour; no instant cut inside)
- wait <ms>          -> HOLD at the most recent waypoint (see below)
- fovdeg <a> <b>     -> optional FOV ramp across the tour
- fov <a> <b>        -> optional FOV ramp in radians
- waypoint lines may include w=<weight> or speed=<factor>

Example: 3-waypoint linear tour
  tour 9000 linear
  moveto 1
  moveto 2
  moveto 3
  endtour

Example: 4-waypoint spline tour
  tour 12000 spline
  moveto 10
  moveto 11
  moveto 12
  moveto 13
  endtour

Fast compact equivalent:
  tour 12000 spline 10 11 12 13

Use the compact form when the tour only needs waypoints and optional FOV ramp.
It avoids waiting for many separate notecard line reads before the tour can
start. Use the block form when you need waypoint holds or per-waypoint weights.
The compact form starts directly at its first preset; put `load <same idx>`
before it if you want the viewer camera to be placed there first.

Wait inside tour = HOLD
- In a tour, "wait <ms>" inserts a hold at the most recent waypoint.
- Holds add extra time ON TOP of the tour movement time.

Example with hold:
  tour 7000 linear
  moveto 1
  wait 1500
  moveto 2
  moveto 3
  endtour

Edge case:
- If a tour has fewer than 2 waypoints at endtour, it is ignored and the
  playlist continues.

9) LOCK (focus only)
--------------------
Lock sets the camera focus to a fixed target while the camera position can
still move (moveto/tour/follow can still move position).

Chat usage:
  /88 lock on
  Locks focus to a point in front of your current camera.

  /88 lock on <128,128,30>
  Locks focus to a fixed world point.

  /88 lock on 01234567-89ab-cdef-0123-456789abcdef
  Locks focus to an object/avatar UUID.

  /88 lock off

Notes:
- In local chat, vectors with spaces are accepted:
  <128, 128, 30> is OK in chat.
- In playlists, write vectors without spaces:
  <128,128,30>
  (Vectors with spaces are not supported in playlists.)

Playlist note:
- In notecards, "lock on" must be written exactly as "on" to enable.
  (Chat also accepts "1"/"true", but notecards do not.)

10) FOLLOW (capture follow)
---------------------------
Follow keeps the camera position/focus relative to a moving target. It is
intended for tracking shots when no moveto/tour is running.

Chat usage:
  /88 follow on
  Follow yourself (default target), mode world, transition 0.

  /88 follow on <uuid> world 500
  Capture-follow a target, in world mode, blending in over 500ms.

  /88 follow on <uuid> yaw 800
  Yaw-only follow (nice for vehicles), blend over 800ms.

  /88 follow off

Modes:
- world: offsets in world space
- local: offsets in target's rotation space
- yaw: only yaw rotation used (stabilizes banking/tilt)

Chat note:
- When you want to provide mode or transition in chat, include the target UUID.
  The short form "/88 follow on yaw 500" is not parsed as mode+transition.

Playlist follow (notecard):
- Syntax:
  follow on|off [uuid] [modeInt] [transition_ms]

- modeInt: 0=yaw, 1=local, 2=world

Deprecated / not supported in playlists (current build):
- Explicit follow offsets in notecards:
  follow on <uuid> <posOffset> <focusOffset> yaw|local|world <transition_ms>
  (This syntax is not parsed by the playlist helper; it will behave as capture-follow instead.)

11) Markers ("show cams") - helper script
-----------------------------------------
Requires HS_CamMarkers.lsl in the HUD.

  /88 show cams [N]
  Rezzes up to N clickable markers near you, one per preset found.

  /88 hide cams
  Cleans up markers.

Clicking a marker:
- Loads that preset (moveto by default)
- Interrupts any running playlist

12) Engine Config (HS_CamEngine.properties)
-------------------------------------------
Engine reads tuning values from a notecard named:

  HS_CamEngine.properties

Commands:
  /88 cfg reload
  /88 cfg dump

Common keys:
  move_step=0.025
  follow_step=0.05
  default_move_ms=3000
  default_focus_dist=10.0

  move_pos_lag=0.5
  move_focus_lag=0.5
  follow_pos_lag=0.5
  follow_focus_lag=0.5

  pos_threshold=0.02
  focus_threshold=0.02

  tour_cam_min_interval=0.033
  tour_pos_epsilon=0.005
  tour_focus_epsilon=0.005

  follow_predict=0.10
  tour_max_points=20

Tuning tips:
- If motion looks steppy: lower move_step (0.03 -> 0.025).
- If script load matters more than maximum smoothness: raise move_step slightly
  (0.025 -> 0.033).
- Tour playback also has an internal camera-frame cap:
  tour_cam_min_interval=0.033 is about 30 Hz. Lowering move_step below this
  still computes the tour more often, but it will not send camera frames faster
  unless tour_cam_min_interval is also lowered.
- tour_pos_epsilon and tour_focus_epsilon skip tiny duplicate tour camera
  updates. Lower values send more updates; higher values reduce script load.
- tour_max_points is capped by the scripts for safety. Very large tours also
  hit link-message payload limits, so split extremely long rides into smaller
  tours if needed.
- If camera feels too mushy: lower move_pos_lag / move_focus_lag.
- If follow jitters: raise thresholds slightly (0.02 -> 0.03).
- If follow trails: raise follow_predict slightly (0.10 -> 0.12).

Reload behavior:
- Reload is asynchronous.
- During an active move/tour, base params may apply after the move ends.

13) Troubleshooting
-------------------
"Nothing happens when I type /88 ..."
- Ensure the HUD is worn and scripts are running.
- Use LOCAL chat, not IM.
- Verify channel: /88 help

"Camera permission denied"
- Run /88 cam on again and accept the popup.
- Some viewers block permission popups; check viewer settings.

"Show cams does not rez markers"
- Parcel may block rez (no-rez).
- Parcel object limits may be reached.
- Ensure HS_CamMarkers helper is present.

"Presets don't save"
- idx must be > 0.
- Linkset Data has capacity limits; avoid excessive preset counts.

"Movement looks choppy"
- Region performance matters.
- Try lowering move_step slightly.
- Use reasonable durations (1500-5000ms for cinematic).

14) Best Practices & Creative Workflows
---------------------------------------
Preset organization:
- 1-20: a single scene
- 100-120: another scene
- 900+: experiments / temporary

Use Tour for ride shots:
  tour 14000 spline
  moveto 1
  moveto 2
  moveto 3
  wait 1200
  moveto 4
  endtour

Use early cut intentionally:
  moveto 10 6000
  wait 900
  load 11

Combine follow + lock for action:
  follow on <subject_uuid> yaw 400
  lock on <target_uuid>
