93 lines
5.1 KiB
C#
93 lines
5.1 KiB
C#
namespace DeepDrftPublic.Client.Services;
|
|
|
|
/// <summary>
|
|
/// Holds the Mix visualizer's four continuous-control positions for the lifetime of the WASM app
|
|
/// instance. Scoped in DI, so it lives across SPA navigations within one listening session — open a
|
|
/// second mix and the sliders keep where you left them — but a fresh page load (F5) constructs a new
|
|
/// instance, resetting to defaults. That matches the spec's "persist within session, reset on fresh
|
|
/// load" without any cookie/localStorage round-trip (see mix-visualizer-webgl-renderer §3c).
|
|
///
|
|
/// One state object, four properties — not four sibling holders (Daniel's decided shape, spec §3c).
|
|
/// Each C#-side default mirrors a TS-side tuning anchor in MixVisualizer.ts; keep the two in sync, as
|
|
/// the existing <c>DefaultVisibleSeconds</c> / <c>DEFAULT_VISIBLE_SECONDS</c> pair does.
|
|
///
|
|
/// <para>
|
|
/// <see cref="Changed"/> is the decoupling seam between the controls row and the visualizer bridge.
|
|
/// The controls component (a sibling of the backdrop in the page tree) only mutates this shared state
|
|
/// and raises <see cref="Changed"/>; the bridge component (<c>MixWaveformVisualizer</c>) subscribes
|
|
/// and pushes the affected uniform to the JS module. This keeps the JS module handle single-owned by
|
|
/// the bridge — no handle sharing, no service-locator, no cross-component interop.
|
|
/// </para>
|
|
/// </summary>
|
|
public sealed class MixVisualizerControlState
|
|
{
|
|
/// <summary>
|
|
/// Default opening window. Mirrors <c>DEFAULT_VISIBLE_SECONDS</c> in MixVisualizer.ts; keep the
|
|
/// two in sync (the TS owns the rendering anchors, this owns the C#-side session default).
|
|
/// </summary>
|
|
public const double DefaultVisibleSeconds = 10.0;
|
|
|
|
// R2 TEMP (Phase 10 reframe Wave R2): the FOUR controls below are re-routed to the new
|
|
// lava physics for Daniel's in-browser test — the JS handle setters map them as:
|
|
// Bubblyness → lava GRAVITY, Detach → lava HEAT, ColorShiftSpeed → COLLISION STRENGTH,
|
|
// Resolution (VisibleSeconds knob) → WAVEFORM WIDTH (see MixVisualizerControls.razor).
|
|
// The defaults are tuned to Daniel's sweet spot (~20% gravity, ~100% heat). Wave R4
|
|
// replaces this with the proper seven-knob set + its own typed properties. Keep these
|
|
// mirrored to the DEFAULT_* anchors in MixVisualizer.ts, as the existing sync discipline.
|
|
|
|
/// <summary>
|
|
/// Default GRAVITY dial (R2 temp; was bulge). Mirrors <c>DEFAULT_BUBBLYNESS</c> in MixVisualizer.ts.
|
|
/// Normalized [0,1]; 0 = near-weightless float, 1 = wax falls + settles fast. Tuned to Daniel's
|
|
/// ~20% sweet spot so the wax is buoyant-dominated and flows.
|
|
/// </summary>
|
|
public const double DefaultBubblyness = 0.2;
|
|
|
|
/// <summary>
|
|
/// Default HEAT dial (R2 temp; was detach). Mirrors <c>DEFAULT_DETACH</c> in MixVisualizer.ts.
|
|
/// Normalized [0,1]; 0 = wax rests at the bottom (collision-only), 1 = lots of small turbulent
|
|
/// bubbles. Tuned to Daniel's ~100% sweet spot.
|
|
/// </summary>
|
|
public const double DefaultDetach = 1.0;
|
|
|
|
/// <summary>
|
|
/// Default COLLISION-STRENGTH dial (R2 temp; was color-shift). Mirrors
|
|
/// <c>DEFAULT_COLOR_SHIFT_SPEED</c> in MixVisualizer.ts. Normalized [0,1]; 0 = soft mush,
|
|
/// 1 = hard elastic throw.
|
|
/// </summary>
|
|
public const double DefaultColorShiftSpeed = 0.5;
|
|
|
|
/// <summary>
|
|
/// Default WAVEFORM-WIDTH dial (R2 temp; routed to the resolution/zoom knob this wave). Mirrors
|
|
/// <c>DEFAULT_WAVEFORM_WIDTH</c> in MixVisualizer.ts. Normalized [0,1]; 1 = full ribbon width
|
|
/// (prior look), lower narrows the band so the lava gets more room. Opens at full width.
|
|
/// </summary>
|
|
public const double DefaultWaveformWidth = 1.0;
|
|
|
|
/// <summary>Visible time-span in seconds (the resolution/zoom control). Reused as-is from 8.K.</summary>
|
|
public double VisibleSeconds { get; set; } = DefaultVisibleSeconds;
|
|
|
|
/// <summary>Bulge amount, normalized [0,1]. Inert until Wave 3 consumes the uniform.</summary>
|
|
public double Bubblyness { get; set; } = DefaultBubblyness;
|
|
|
|
/// <summary>Lava-lamp detachment, normalized [0,1]. Inert until Wave 3 consumes the uniform.</summary>
|
|
public double Detach { get; set; } = DefaultDetach;
|
|
|
|
/// <summary>Gradient-morph rate, normalized [0,1]. Inert until Wave 3 consumes the uniform.</summary>
|
|
public double ColorShiftSpeed { get; set; } = DefaultColorShiftSpeed;
|
|
|
|
/// <summary>
|
|
/// Waveform width, normalized [0,1]. R2 TEMP: routed to the resolution/zoom knob for in-browser
|
|
/// testing (Wave R4 gives it its own knob and restores the resolution knob to VisibleSeconds).
|
|
/// </summary>
|
|
public double WaveformWidth { get; set; } = DefaultWaveformWidth;
|
|
|
|
/// <summary>
|
|
/// Raised whenever any control value changes. The visualizer bridge subscribes to push the
|
|
/// affected uniform(s). Mutators set the property then raise this; subscribers re-read the values.
|
|
/// </summary>
|
|
public event Action? Changed;
|
|
|
|
/// <summary>Raise <see cref="Changed"/>. Called by the controls component after mutating a value.</summary>
|
|
public void NotifyChanged() => Changed?.Invoke();
|
|
}
|