diff --git a/DeepDrftPublic.Client/Controls/MixWaveformVisualizer.razor.cs b/DeepDrftPublic.Client/Controls/MixWaveformVisualizer.razor.cs index 78b2db6..a3c542a 100644 --- a/DeepDrftPublic.Client/Controls/MixWaveformVisualizer.razor.cs +++ b/DeepDrftPublic.Client/Controls/MixWaveformVisualizer.razor.cs @@ -59,7 +59,7 @@ public partial class MixWaveformVisualizer : ComponentBase, IAsyncDisposable // `[MixVisualizer]`, same as the JS logs so the two interleave into one timeline). These pinpoint // which upstream link is broken when the ribbon stays blank — set false once confirmed healthy. // ON for the Phase 10 reframe Wave R4 controls test (matches the JS-side DEBUG in - // MixVisualizer.ts). Daniel evaluates the seven-knob bar + pause behavior in-browser; flip back to + // MixVisualizer.ts). Daniel evaluates the eight-knob bar + pause behavior in-browser; flip back to // false at reframe close along with the JS flag. private static readonly bool Debug = true; private const string Tag = "[MixVisualizer]"; diff --git a/DeepDrftPublic.Client/Services/MixVisualizerControlState.cs b/DeepDrftPublic.Client/Services/MixVisualizerControlState.cs index c9891c3..7477b12 100644 --- a/DeepDrftPublic.Client/Services/MixVisualizerControlState.cs +++ b/DeepDrftPublic.Client/Services/MixVisualizerControlState.cs @@ -30,9 +30,10 @@ public sealed class MixVisualizerControlState // sweet spot (§4c). /// - /// Default scroll-speed dial. Mirrors DEFAULT_SCROLL_SPEED in MixVisualizer.ts. Normalized - /// [0,1] → mapped to the visible time-span via (0 = slow/wide window, - /// 1 = fast/tight window). Opens mid-range. + /// Default scroll-speed dial. Normalized [0,1] → mapped C#-side to a visible time-span in seconds + /// via , then sent to MixVisualizer.ts as a seconds value via + /// setScrollSpeed. The TS-side anchor is DEFAULT_VISIBLE_SECONDS. Opens mid-range + /// (0 = slow/wide window, 1 = fast/tight window). /// public const double DefaultScrollSpeed = 0.5; diff --git a/DeepDrftPublic/Interop/visualizer/MixVisualizer.ts b/DeepDrftPublic/Interop/visualizer/MixVisualizer.ts index 12b9851..49bdb1a 100644 --- a/DeepDrftPublic/Interop/visualizer/MixVisualizer.ts +++ b/DeepDrftPublic/Interop/visualizer/MixVisualizer.ts @@ -1426,9 +1426,9 @@ export function create(canvas: HTMLCanvasElement): MixVisualizerHandle { * toe) keeps the low end gentle so small dial moves near 0 don't suddenly erupt. */ function heatScaleFromDial(dial: number): number { const d = Math.min(Math.max(dial, 0), 1); - // Smoothstep toe (gentle at 0) scaled to reach 1.2 at dial 1 — Phase 10 §3.4: ~20% stronger - // at the high end so full heat roils harder. The low/mid feel is unchanged (the toe dominates - // there); only the top end gains the extra 20% drive into the floor-heating + buoyancy + turbulence. + // Smoothstep toe (gentle at 0) scaled by 1.2 — Phase 10 §3.4: uniform +20% across the curve + // (every non-zero dial position is raised by 20%; the shape of the toe is preserved but the + // overall output is higher at every point). return d * d * (3 - 2 * d) * 1.2; } @@ -1601,7 +1601,8 @@ export function create(canvas: HTMLCanvasElement): MixVisualizerHandle { b.vx += sideSign * WAVE_COLLIDE_SPRING * penetration * dt * (1 - collideHardness); // Hard elastic reflection (hard end): bounce the inward velocity back out, scaled - // by restitution × hardness (over-unity restitution at the top = the springy throw). + // by restitution × hardness. Restitution is sub-unity (≤ 0.85) — bounded reflection, + // no energy added. if (inwardSpeed > 0) { b.vx += sideSign * inwardSpeed * (1 + waveRest) * collideHardness; } @@ -1613,9 +1614,9 @@ export function create(canvas: HTMLCanvasElement): MixVisualizerHandle { const throwUp = Math.min(WAVE_THROW_UP * penetration * dt * collideHardness, WAVE_THROW_UP_MAX); b.vy -= throwUp; - // Positional push-out: always eject the wax fully out of the ribbon along the normal so - // it can never lodge inside (Daniel "gets stuck"). The soft end eases it out gently - // (mushy), the hard end snaps it clean — but both clear the boundary, so no stuck wax. + // Positional push-out: ejects the wax progressively out of the ribbon along the normal + // (converges across substeps, so no stuck wax). The soft end eases it out gently + // (mushy), the hard end snaps it clean. b.x += sideSign * penetration * (0.5 + 0.5 * collideHardness); }