﻿================================================================
 HS2 Auto Wipe Camera   v1.27.0
 Picture-in-picture wipe cameras for HoneySelect 2 / StudioNEOV2
================================================================

Overlays close-up windows ("wipes") of your dancers on top of the studio view,
the way a TV broadcast or a multi-camera live stream does. The whole layout
builds itself when you load an MMD dance - there is nothing to set up per dance.


■ What makes it different

* No per-dance setup.
  You never pick who to follow or which bone to track. The plugin works out who
  is dancing on its own. Framing is expressed as a SHOT SIZE - face, bust,
  waist, legs, full body, rear - and every distance is measured in multiples of
  that character's own head-to-hip length, so "bust shot" frames the same way on
  a tall model, a short one, or an MMD model that has been rescaled.

* The layout rebuilds itself from the dancer count.
  One dancer gets two wipes (her face and her rear), two dancers get four (each
  one's face and rear in the four corners), and so on, up to six wipes. Swap the
  dance and the layout follows. If you do not like a layout, arrange the wipes
  however you want and press "remember this as the layout for N dancers" - it
  comes back next time that many people are dancing.

* The wipe image matches the main view.
  HS2's character light is camera relative, so a naive second camera looks at
  the unlit far side of the subject and the wipe comes out dark. This plugin
  re-aims that light at the wipe's viewpoint while it renders, and either ports
  the post-processing stack across or borrows the studio camera itself, so
  colour grading and tone match the main view.

* Wipes can go out to their own window, a phone, or OBS (MJPEG streaming).


■ Requirements

* HoneySelect 2 (StudioNEOV2)
* BepInEx 5.4.x

No plugin dependencies are required. These two are optional:

* CharaAnime
    Used to tell who is actually dancing. Without it the plugin falls back to
    VMDPlayPlugin (MMDD) plus motion energy and where the main camera is aimed.
* HS2_CamReaction
    Only if you have it: lets a wipe caption show the device level and count.
    Without it those caption fields simply disappear.

Built for the studio (StudioNEOV2).


■ Install

  Copy HS2_AutoWipeCam.dll into

      <your HS2 folder>\BepInEx\plugins\

  NOTE: the DLL cannot be overwritten while the game is running (the file is in
  use). Close the game before updating it.

  To uninstall, delete the DLL. Settings live in
  BepInEx\config\syuba.hs2.autowipecam.cfg - delete that too if you want a
  clean removal.


■ First run

  1. Open the studio and load an MMD dance as usual
  2. Press F6       -> the wipes appear
  3. Press Shift+F6 -> settings panel

  The wipes start switched off. While you are posing characters or building a
  scene, a second render of the scene is just dead weight, so nothing happens
  until you press F6.

  The panel is in English by default. Set Language to Japanese at the top of
  the panel for a Japanese UI (it loads a font from the OS).


■ Hotkeys

  F6              toggle ALL wipes (master switch)
  Ctrl + F6       toggle only the selected wipe
  F7              cycle shot size (Face -> Bust -> Waist -> Legs -> Full -> Hip)
  Shift + F7      jump to the rear shot (press again to go back)
  Shift + F6      settings panel

  Hotkeys act on the SELECTED wipe, which is outlined in orange while the panel
  is open. Rebind them under "9. Keys" in the panel or in the cfg file.


■ The settings panel

  Shift + F6 opens it. Drag the bottom-right corner to resize; position and size
  are remembered. While the panel is open you can drag wipes around with the
  left mouse button; a dragged wipe snaps to the screen edges, the screen
  centre, and the edges of the other wipes.

  Shot size
      Face / Bust / Waist / Legs / Full / Hip

  Angle
      Auto (a stock angle per shot) / Front / Fixed yaw / Orbit / Same as main.
      "Auto" means choosing a shot size also chooses the angle: a dead-on front
      view looks like security footage, so shots are swung off to
      three-quarters, and the legs and rear shots are taken from below. The
      pitch and yaw sliders act as +/- offsets from that stock angle.

  Target
      Automatic, or a specific character.

  Window
      Corner, shape (9:16 portrait etc.), size, offset, opacity, border.
      Border colour is per wipe - with six wipes on screen the border colour is
      what tells you which one is whom.

  This wipe's cost
      Frame rate (default 30fps) and render height (default 720), per wipe.

  Copy settings
      Build one wipe, then hand its look to the others. Position and target are
      deliberately NOT copied, or the pasted wipe would land on top of the one
      you copied from.

  Presets
      Five slots, each holding a WHOLE per-dancer-count table - "with 1 dancer
      do this, with 2 do this, with 3 do this" is one preset.

  Caption on each wipe    -> see below
  Screen layout           -> see below
  Shared settings         language, render mode, auto layout on/off, etc.


■ Automatic layout

  The plugin counts the dancers MMDD has motions loaded on and rebuilds to match:

    0 dancers    1 wipe    bust shot of whoever the main camera is on
    1 dancer     2 wipes   her face and her rear, along the bottom
    2 dancers    4 wipes   each one's face and rear, in the four corners
    3 dancers    3 wipes   three rear shots along the bottom
    4 dancers    4 wipes   one rear shot in each corner
    5+           one per dancer (max 6), in a row along the bottom

  The count has to hold still for 1.5 seconds before anything is rebuilt -
  characters and their motions arrive over several frames while a scene loads,
  and rebuilding on an intermediate count looks broken.

  The layout is only rebuilt when the COUNT changes, so anything you adjust by
  hand afterwards survives until you swap the dance.

  With two or more dancers each wipe is pinned to its subject. Left on
  automatic, the wipes would trade subjects every time you swing the main
  camera.

  "Remember this as the layout for N dancers" saves your own arrangement:
  subject, shot size, window, the full framing set (angle mode, pitch, yaw,
  zoom, FOV, height) and the screen layout for that dancer count. Frame rate and
  render height are deliberately NOT saved - those are machine settings, not
  part of the composition.

  Automatic layout can be switched off entirely under "Shared settings"; the
  wipe count then becomes manual (+ / -).


■ Screen layout (when you do not want wipes over the dance)

  Instead of overlaying, the dance image itself can be pushed to one side of the
  screen and reshaped, leaving the free side as a dedicated wipe area.

    Placement   Overlay (classic) / Centre / Left / Right / Top / Bottom
    Shape       Same as screen / 16:9 / 4:3 / 3:4 / 1:1
    Size        percentage of screen height

  Being able to change the SHAPE is the point. Shrinking the dance image at its
  original aspect only leaves thin margins that nothing fits into; a 4:3 image
  at full height on the left leaves one usable column on the right. "Centre"
  gives you a wipe area on both sides.

  "Fill that area with the wipes" tiles the active wipes into the free area on
  a grid, picking whichever column count makes them largest.

  NOTE on "Keep the same width of view" (default ON):
    Unity keeps the VERTICAL field of view when you change aspect, so a taller
    image simply crops the sides and your dancer walks out of frame. This option
    keeps the horizontal field of view instead. It does cost frame rate - the
    camera genuinely sees more world (about 1.33x more at 16:9 -> 4:3, about
    1.78x at 16:9 -> 1:1). Turn it off, or stay near 4:3, if it hurts.


■ Captions on the wipes

  Four fields - number, character name, device level, climax count - each placed
  independently at None / top-left / top-right / bottom-left / bottom-right.
  Fields sharing a corner sit on one line. There are buttons to send all four to
  one corner at once.

  Device level and count only appear when HS2_CamReaction is installed.

  Captions are drawn as UI on the game screen, so they are NOT part of the MJPEG
  stream below.


■ Streaming to another window, a phone, or OBS (MJPEG)

  Turn on "Stream wipes to their own windows" under "7. Streaming" and each wipe
  becomes an MJPEG feed:

    http://127.0.0.1:8787/      index page with every active wipe
    http://127.0.0.1:8787/0     a single wipe (for its own window)

  A single <img> tag is enough to receive it, so a browser window, an OBS
  browser source or an Electron frame all work with no client code at all.
  This also works around the screenshot limit below: the stream can be captured
  separately.

  Watching from a phone or tablet:
    Set "Who can watch" to LocalNetwork and any device on the same Wi-Fi can
    watch. The URL to type is printed in the log at startup. /m is the mobile
    page (full screen, tap for the toolbar, swipe to change wipe).

    !! There is NO authentication. While it is set to LocalNetwork, anyone who
       can reach that port can watch. Do not use it on a shared network, and set
       it back to ThisPcOnly when you are done.

  Streaming reuses the same render the on-screen wipe already produced, so
  nothing extra is drawn for it - you only pay for the readback and the JPEG
  encode. The encode has to run on the main thread, though, so wipes x fps lands
  directly on the CPU. One or two streams is the practical limit; drop Stream
  height to 360 and Stream frame rate to 10 if it hurts.

  If the streamed image comes out upside down, turn on "Flip the streamed image"
  (default off - no flip was needed on the DX11 machine this was built on).


■ Render modes

  Dedicated camera (default)
      Renders with its own camera and ports the post-processing layer across.
      Cheap, but effects implemented as components on the main camera (DHH and
      friends) are not there.

  Shared camera
      Borrows the studio's main camera for an instant, so every effect is
      present and the wipe cannot disagree with the main view. Costs much more.

  In both modes the character light is re-aimed at the wipe while it renders
  ("Light follows wipe"). Turn that off and the wipes go dark.


■ If it runs slow

  A wipe is a second render of the scene, so a naive implementation roughly
  doubles GPU load. In order of effect:

    1. "Wipe shadows" OFF (this is the default).
       Shadow maps are re-rendered per camera and do NOT get cheaper at lower
       resolution. On its own this is the single biggest saving.
    2. Keep the render mode on "Dedicated camera" (default).
    3. Lower the wipe frame rate (default 30fps -> 12-15).
    4. Lower the render height (default 720 -> 360).
    5. Use fewer wipes.

  Multiple wipes are deliberately offset in time so they never all render on the
  same frame.


■ Limitations

  * Wipes are drawn as a UI overlay. They show up in a desktop capture (OBS) but
    NOT in Screencap screenshots, which only take the camera's render. Use the
    MJPEG stream if you need them in a capture.
  * Wipe settings are not stored in the scene file - they are BepInEx config,
    one set globally. Not having to change anything per dance is the whole point.
  * The dedicated camera mode does not carry every effect (see above).


■ Troubleshooting

  The wipe shows the back of her head
      Turn on "Flip facing".

  The wipe image is upside down
      Turn on "Flip vertically" for that wipe.

  The panel shows boxes instead of text
      Set Language to English (no Japanese font was found on this system).

  The dancer count is wrong, or the layout never builds
      Check the source line in the panel. With CharaAnime installed the plugin
      uses its model register; without it, it estimates from MMDD.

  I updated the plugin and nothing changed
      BepInEx prefers the values already written to the config file over new
      defaults. Press the "all wipes" reset once in the panel. That only resets
      framing - window position, size, resolution and frame rate are kept.

  A hotkey does nothing
      Another plugin is probably using it. Rebind under "9. Keys".

  Nothing happens at all
      Check BepInEx\LogOutput.log for an "Auto Wipe Camera" line.


■ License

  Do whatever you like with it - modify it, redistribute it, publish your own
  version. Credit is appreciated but not required. No warranty.


■ Author

  syuba
