Skip to content

feat: continuous osc latent navigation - #45

Open
ucodia wants to merge 5 commits into
mainfrom
feat/osc-latent-navigation
Open

feat: continuous osc latent navigation#45
ucodia wants to merge 5 commits into
mainfrom
feat/osc-latent-navigation

Conversation

@ucodia

@ucodia ucodia commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

OSC-bound parameters can now navigate the latent seed space continuously instead of jumping between integer seeds. The seed binding accepts fractional values, a new seed y binding exposes the second grid axis, and the seed-mode UI shows the absolute X/Y coordinates (the same values OSC writes) instead of fractional offsets. The renderer needed no changes: it already bilinearly blends the 4 seeds around a fractional coordinate.

Details:

  • osc_handler now casts with an explicit type per binding instead of the runtime type of the target, which is what truncated OSC values to integers (latent.x started as int and was reset to int by the seed box).
  • OscMenu.set_params backfills state-dict keys missing from older presets, so presets saved before the seed y key existed load cleanly (and any future key addition is preset-safe).
  • The seed integer box is kept: it remains a lossless readout of the nearest seed and typing a seed still jumps to it.

Usage: bind a fader to seed with a mapping expression like x*20 for a smooth sweep through 20 seeds, or an XY pad to seed + seed y for 2D roaming.

Type of change

  • Feature
  • Fix
  • Other (docs, refactor, chore, ci, etc.)

How was this tested?

Verified by automated tests and static checks:

  • 11 new headless unit tests (tests/test_osc_menu.py, tests/test_latent_widget_osc.py): float storage through the handlers, type stability after int assignment, exact OSC menu key sets, end-to-end delivery through the menu wrapper including a mapping expression (x*20), and preset backfill round-tripped through pickle. Full suite: 26 passed.
  • uv run zensical build passes for the docs change.
  • Traced the render path: viz.args.seeds flows into the existing bilinear seed blending in widgets/renderer.py unchanged; fractional, negative, and large values all resolve to valid seeds.

Still needs manual GUI verification (cannot be driven headlessly):

  • Bind an OSC fader to seed with mapping x*5, sweep 0 to 1: image morphs continuously, no jumps at integer boundaries.
  • Bind an XY pad to seed and seed y: smooth 2D roaming.
  • Seed box readout tracks X/Y edits and Drag; typing a seed jumps to it and resets Y to 0.
  • Save a preset with active OSC bindings and reload it: bindings intact.
  • Load a preset saved before this change: no errors, seed y appears in the OSC menu with defaults.
  • Re-capture docs/assets/live-module-latent-space-01.png (still shows the old fractional boxes).

Checklist

  • PR title follows Conventional Commits without a scope (<type>: <subject>)
  • I have read CONTRIBUTING.md
  • Documentation in docs/ or README.md is updated if user-visible behavior changed
  • If this PR adds new runtime files, they are included in release.py (no new runtime files)
  • Screenshots or a short clip are attached for UI changes (pending manual verification pass)

Co-authored with an AI coding tool.

Generated with AI assistance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant