No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
deadshark 🌙✨🦇🌃 a4e1f8cb36
Chara Maker accessory editing, Undo/Redo, Mirror, and a rebuilt HUD (#3)
* Add MouseWrapService for infinite mouse-drag tracking

Introduces MouseWrapService, which tracks an unbounded "virtual" mouse
position while a transform mode is active. The real OS cursor is
confined to the game window (Cursor.lockState = Confined), and whenever
it gets near an edge it is warped to the opposite edge via SetCursorPos,
while the virtual position keeps accumulating movement seamlessly - the
jump is never visible to anything reading VirtualMousePosition.

This file is self-contained and not wired into anything yet; it will be
consumed by Transformer.cs and TOHYK.cs in follow-up commits.

* Register MouseWrapService.cs in the shared project

Adds the Compile entry so MouseWrapService.cs is included in both the
KK and KKS builds via the shared project.

* Use infinite mouse-drag and fix axis-constrained rotation in Transformer

Switches all mouse reads in Transformer.cs from Input.mousePosition to
MouseWrapService.VirtualMousePosition, so move/rotate/scale math no
longer sees the edge-warp jumps.

Also adds ComputeConstrainedRotateAngle(), replacing the implicit
atan2-around-pivot rotation math with a linear mapping of mouse travel
along the on-screen tangent of the rotation axis - the same
direction-agnostic approach already used by free rotate. Falls back to
the circular (atan2) behavior only when the axis points almost straight
at/away from the camera, where no meaningful tangent exists.

* Wire up infinite mouse-drag and constrained-rotation fix in TOHYK.cs

Calls MouseWrapService.Tick() each frame, and BeginTracking()/
EndTracking() when entering/leaving a transform mode. Switches all
remaining mouse reads to MouseWrapService.VirtualMousePosition.

UpdateRotateConstrained() now just resolves the rotation axis and
delegates the angle computation to
Transformer.ComputeConstrainedRotateAngle(), removing the old manual
atan2-around-pivot logic.

* Add cursor icons for Move/Rotate/Scale

Adds the source PNGs (256x256) used to draw the custom cursor icon for each transform mode.

* Add CursorService to draw a custom per-mode cursor

New static class that replaces the OS cursor with a custom GPU-drawn icon (via OnGUI) while a transform mode is active, avoiding native cursor caching issues when rotating bitmaps on Windows/Unity. Includes box-filter downscaling and configurable antialiasing.

* Include CursorService.cs and cursor resources in the shared project

Adds the required Compile/EmbeddedResource entries so CursorService.cs and the cursor PNGs get compiled/embedded into both the KK and KKS projects.

* Add dashed pivot-to-cursor guide line

New RenderCursorGuideLine method (+ DrawDashedLine2D helper) that draws a Blender-style dashed line, in screen space, from the pivot to the virtual mouse position during Rotate/Scale.

* Wire up the custom cursor and dashed guide line

Adds the BepInEx config options (cursor size and antialiasing), hooks CursorService into mode changes (SetForMode/Reset), and adds DrawCustomCursor in OnGUI. Also invokes RenderCursorGuideLine during Rotate/Scale.

* Enable AllowUnsafeBlocks in TOHYK.KK

Adds AllowUnsafeBlocks to the csproj, required by the new texture manipulation code in CursorService.

* Bump to .NET 4.6.2 and enable AllowUnsafeBlocks in TOHYK.KKS

Bumps TargetFrameworkVersion from v4.6 to v4.6.2 and adds AllowUnsafeBlocks, required by CursorService.

* Migrate TOHYK.KK from NuGet to direct references in ref/KK

- Replace packages.config references with direct DLL references
  located in ../ref/KK (0Harmony, Assembly-CSharp, BepInEx,
  ExtensibleSaveFormat, KKAPI, TextMeshPro, UnityEngine, UnityEngine.UI)
- Mark references as Private=False
- Remove NuGet analyzers and the EnsureNuGetPackageBuildImports
  target, no longer needed

* Delete TOHYK.KK/packages.config

* Migrate TOHYK.KKS from NuGet to direct references in ref/KKS

- Replace packages.config references with direct DLL references
  located in ../ref/KKS (0Harmony, Assembly-CSharp, BepInEx, KKSAPI,
  KKS_ExtensibleSaveFormat, Sirenix.Serialization, UniRx, UniTask
  and its submodules, Unity.TextMeshPro, UnityEngine and its
  submodules)
- Mark references as Private=False
- Add KKS compilation constant to both Debug and Release
  configurations, enabling KKS-specific conditional code
- Remove NuGet analyzers and the EnsureNuGetPackageBuildImports
  target, no longer needed

* Delete TOHYK.KKS/packages.config

* Add Alt key support to AxisInput

- Add IsAltHeld property to the AxisInput struct
- Extend the constructor with an optional isAltHeld parameter
  (defaults to false, preserving backward compatibility)
- Update equality operator and GetHashCode to account for the
  new IsAltHeld state

* Simplify CursorService embedded resource loading via KKAPI

- Replace manual reflection-based embedded resource loading
  (LoadEmbeddedBytes) with KKAPI's ResourceUtils.GetEmbeddedResource
- Remove now-redundant custom resource name matching logic
- Trim verbose XML doc comments to reduce noise; behavior is
  unchanged

* Add Mirror transform mode and new pivot origin options

- Add Mirror value to the transform mode enum
- Add BoundingBoxCenter and AccessoryParent values to the pivot
  origin enum

* Use ITransformTarget interface in GuideRenderer, refresh axis colors

- Replace GuideObject with the new ITransformTarget interface as
  the parameter type in Render, DrawConstraintVisual, and
  GetConstraintAxisDir, so guides work with any transformable
  target (objects and accessories alike)
- Update the X/Y/Z axis constraint colors to more vivid tones
- Remove an outdated XML doc comment on RenderCursorGuideLine

Note: depends on the new ITransformTarget interface.

* Add hotkeys for Chara Maker toggle, Undo/Redo, clear transform, Mirror, and camera focus

- Add configurable hotkeys: Toggle Chara Maker Mode (Tab), Undo
  (Ctrl+Z), Redo (Ctrl+Y), Clear Position/Rotation/Scale
  (Alt+G/R/S, Blender-style), Mirror (Ctrl+M), and Focus Camera
  On Selection (F, also hardcoded to Numpad '.')
- Add GetClearTransformInput() to report which clear-transform
  hotkey was pressed
- Extend GetAxisInput()/BuildAxisInput() to also detect Alt,
  passing it through to the new AxisInput.IsAltHeld
- Add IsFineSnap and IsPrecision helpers based on Shift/Alt state
- Remove a stray profanity-laden comment

* Use ITransformTarget interface in MeshRaycaster

- Replace GuideObject with the new ITransformTarget interface as
  the dictionary value type in Raycast, BuildCache,
  BuildTargetCollidersCache, and BuildExcludeSet, so raycasting
  works against any transformable target (objects and accessories)

* Trim explanatory comments in MouseWrapService

- Remove verbose XML doc and inline comments describing the
  infinite-drag mouse warp behavior
- No functional changes

* Register new accessory/pivot source files in shared project

- Add compile entries for the new files: AccessoryModeService.cs,
  AccMoverBridge.cs, AccessoryTransformTarget.cs, InputGuard.cs,
  ITransformTarget.cs, StudioGuideTarget.cs, and
  PivotGeometryUtils.cs

Note: project will not build until the new source files are
added in subsequent commits.

* Add Chara Maker accessory support, Undo/Redo, Mirror mode, numeric input, and camera focus

- Support transforming accessories in Chara Maker in addition to
  Studio objects, via the new ITransformTarget abstraction
- Add Undo/Redo for accessory transforms in Chara Maker
- Add Blender-style Mirror mode (Ctrl+M) to flip position/
  rotation/scale of the selection across the pivot on a chosen axis
- Add Blender-style Clear Transform (Alt+G/R/S) to instantly reset
  position, rotation, or scale
- Add numeric input during an active transform, letting the user
  type an exact value instead of dragging the mouse
- Add camera focus on the current accessory selection in Chara
  Maker (F key / Numpad '.')
- Add configurable HUD options: status bar position/size and
  enabled-badge position/size, plus fade duration
- Add precision (Alt) and fine-snap (Shift) modifiers during
  transforms
- Improve scale computation to account for the mesh's local axis
  alignment (ComputeMeshScaleFactor / AxisAlignmentWeight)

Note: this is a large, foundational change - most of the new
Shared source files (AccessoryModeService, AccMoverBridge,
AccessoryTransformTarget, ITransformTarget, InputGuard,
StudioGuideTarget) are used directly by this file.

* Rework transform math for per-frame deltas, precision mode, and Mirror

- Change ComputeMoveDelta, ComputeConstrainedRotateAngleDelta (was
  ComputeConstrainedRotateAngle), and the new
  ComputeScaleFrameRatio to compute per-frame deltas from the
  previous mouse position instead of absolute deltas from the
  transform's start, enabling Undo/Redo and Mirror to compose
  correctly
- Add a "precision" modifier (Alt) that scales move/rotate/scale
  deltas down by a fixed factor
- Add a "fine snap" modifier that divides the snap increment by
  100 for finer control
- Split scale snapping into its own ApplyScaleSnapping method
- Simplify constrained rotation to always use the pivot-relative
  screen angle, removing the old tangent-based fallback for
  axes facing the camera
- Replace GuideObject with ITransformTarget in constraint/plane
  helper methods
- Add static MirrorAcrossPlane helper to reflect a position/
  rotation/scale across an arbitrary world-space plane, powering
  the new Mirror mode

* Redesign HUD as a rounded pill with fade, add accessory mode badge

- Replace the plain shadowed text label with a procedurally drawn
  rounded "pill" background (squircle-shaped caps, supersampled
  for smooth edges), cached as static textures
- Add smooth fade in/out for the status bar, driven by the new
  CfgHudFadeDuration setting
- Add a new "TOHYK Enabled" badge shown while accessory mode is
  active in Chara Maker, with its own configurable position/size
- Extend the status bar text to show Mirror mode instructions,
  Precision, Fine Snap, and live numeric input
- Rename pivot mode labels: Median -> Center, Active -> Last
  Selected, Individual -> Each Own Origin; add labels for the new
  Box Center and Parent Bone pivot modes
- Add a "View Axis" label for the new CameraForward constraint
- Cache GUIStyle and text size calculations per font size/text to
  avoid rebuilding them every frame

* Add accessory Undo/Redo stack and Mirror undo support

- Replace GuideObject with ITransformTarget across all Push*Undo
  methods, reading PosLocal/RotLocal/ScaleLocal instead of
  changeAmount
- Add PushMirrorUndo to record position/rotation/scale changes
  from the new Mirror mode
- Add a self-contained Undo/Redo stack for Chara Maker accessories
  (up to 50 steps), since accessories aren't covered by the game's
  built-in Studio UndoRedoManager
- Support undoing/redoing an accessory's parent-bone reassignment
  alongside its transform (KKS only)
- Add CanUndoAccessory/CanRedoAccessory, PushAccessoryUndo,
  UndoAccessory, RedoAccessory, and ClearAccessoryUndo

* Add ITransformTarget interface

- Introduce a common interface for anything TOHYK can transform:
  local position/rotation/scale, which axes are enabled
  (enablePos/enableRot/enableScale), the pivot offset, and a
  Commit() method to apply pending changes
- Lets the same transform/guide/undo code work uniformly against
  both Studio GuideObjects and Chara Maker accessories

* Add StudioGuideTarget wrapper for Studio GuideObject

- Implement ITransformTarget on top of the game's Studio
  GuideObject, mapping PosLocal/RotLocal/ScaleLocal to
  transformTarget.localPosition/localEulerAngles/localScale and
  keeping GuideObject.changeAmount in sync
- Derive PivotOffsetLocal from the object's mesh bounds via
  PivotGeometryUtils
- Commit() is a no-op, since Studio applies GuideObject changes
  directly and immediately

* Add AccessoryTransformTarget for Chara Maker accessories (KKS)

- Implement ITransformTarget for Chara Maker accessories, wrapping
  a ChaControl slot/correction index pair
- Support resolving and reassigning the accessory's parent bone
  (TryResolveBone, SetParentKey), including partsOfHead and
  reverse-parent lookup for mirroring
- Commit() pushes the local transform into the game's accessory
  system via SetAccessoryPos/SetAccessoryRot/SetAccessoryScl,
  syncs the saved coordinate file, and refreshes the accessory
  move UI
- KKS-only (wrapped in #if KKS), since accessory adjust in Chara
  Maker isn't available in the base game

* Add InputGuard to suppress game hotkeys while TOHYK is active

- Add a Harmony-based guard that intercepts Input.GetKey/
  GetKeyDown/GetKeyUp for the set of keys TOHYK owns (G, R, S,
  axis keys, P, C, M, Escape, F, Numpad Period), so the game
  doesn't also react to them while a TOHYK operation is active
- Add a separate suppression path for numeric-entry keys (digits,
  keypad, decimal point, backspace) while numeric input is active
- Add an optional UI-click-blocking patch on GraphicRaycaster,
  used to prevent clicks from reaching game UI during certain
  TOHYK operations (e.g. Mirror axis selection, numeric entry)
- Patches are applied/removed lazily, only while actually needed

* Add optional AccMover integration bridge for multi-accessory selection (KKS)

- Detect the third-party AccMover mod at runtime via reflection
  (no hard dependency), supporting both its public SelectedAccs()
  method and an older internal selectedTransform field as fallback
- Expose TryGetSelectedSlots() so TOHYK can read AccMover's
  current multi-selection and transform several accessories
  together
- Gracefully disable the integration for the rest of the session
  if an incompatible AccMover version throws, logging a warning
  instead of crashing
- KKS-only (wrapped in #if KKS)

* Add AccessoryModeService to bridge TOHYK with Chara Maker's accessory UI (KKS)

- Detect whether the Chara Maker accessory move panel is open and
  which accessory slot/correction is currently selected
- Build AccessoryTransformTarget(s) for the active accessory,
  falling back to a single target when AccMover isn't installed or
  has nothing multi-selected
- Integrate with AccMoverBridge to support transforming multiple
  selected accessories together, with debug logging behind the new
  CfgDebugAccMover setting
- Add RefreshMoveWindowUI/RefreshParentUI to push updated values
  back into the game's accessory move and parent-bone UI after a
  TOHYK edit
- KKS-only (wrapped in #if KKS)

* Add PivotGeometryUtils for mesh-bounds-based pivot offset

- Add GetBoundsCenterOffsetLocal, which combines the bounds of all
  MeshRenderers and SkinnedMeshRenderers under a transform and
  returns the combined center in that transform's local space
- Powers the new Box Center pivot mode, used by both
  StudioGuideTarget and AccessoryTransformTarget

---------

Co-authored-by: Fox <36754166+rnetiks@users.noreply.github.com>
2026-07-18 06:01:29 +02:00
TOHYK.KK Chara Maker accessory editing, Undo/Redo, Mirror, and a rebuilt HUD (#3) 2026-07-18 06:01:29 +02:00
TOHYK.KKS Chara Maker accessory editing, Undo/Redo, Mirror, and a rebuilt HUD (#3) 2026-07-18 06:01:29 +02:00
TOHYK.Shared Chara Maker accessory editing, Undo/Redo, Mirror, and a rebuilt HUD (#3) 2026-07-18 06:01:29 +02:00
.gitignore Initial commit of TOHYK 2026-06-10 23:30:37 +02:00
TOHYK.sln Initial commit of TOHYK 2026-06-10 23:30:37 +02:00