update
This commit is contained in:
73
Program.cs
73
Program.cs
@@ -12,24 +12,27 @@ public class Program
|
||||
private const double DrawFrequency = 60.0;
|
||||
private static Scenario scenario;
|
||||
|
||||
// Speed control
|
||||
private static double desiredSpeed = 0.0001;
|
||||
//private static double desiredSpeed = 1;
|
||||
// Speed control (existing + new throttle)
|
||||
private static double desiredSpeed = 0.01;
|
||||
private static double currentSpeed = desiredSpeed;
|
||||
private const double MinSpeed = 0.0001;
|
||||
private const double MaxSpeed = 1.0;
|
||||
private const double ScrollFactor = 1.1;
|
||||
|
||||
// Space‑toggle state
|
||||
private static double lastDesiredSpeed = 0.1; // remembers the last non‑1.0 speed
|
||||
private static bool isRealTime = false; // starts in slow‑mo (desiredSpeed != 1.0)
|
||||
private static double lastDesiredSpeed = 0.1;
|
||||
private static bool isRealTime = false;
|
||||
|
||||
// Throttle smoothing
|
||||
private static double targetThrottle = 0.0; // 1.0 when W is pressed, 0.0 otherwise
|
||||
private static double currentThrottle = 0.0;
|
||||
private const double ThrottleSmoothing = 8.0; // rate of change
|
||||
|
||||
private static volatile bool running = true;
|
||||
|
||||
public static void Main()
|
||||
{
|
||||
var mode = new VideoMode(new Vector2u(1280, 720));
|
||||
var window = new RenderWindow(mode, "FluidSim - Helmholtz Resonator");
|
||||
var window = new RenderWindow(mode, "FluidSim - Engine (W = throttle)");
|
||||
window.SetVerticalSyncEnabled(true);
|
||||
window.Closed += (_, _) => { running = false; window.Close(); };
|
||||
window.MouseWheelScrolled += OnMouseWheel;
|
||||
@@ -39,12 +42,7 @@ public class Program
|
||||
soundEngine.Volume = 70;
|
||||
soundEngine.Start();
|
||||
|
||||
// Choose one scenario. The Helmholtz resonator is fully updated.
|
||||
//scenario = new HelmholtzResonatorScenario();
|
||||
//scenario = new PipeResonatorScenario(); // needs update to new API
|
||||
//scenario = new SodShockTubeScenario(); // needs update to new API
|
||||
scenario = new EngineScenario(); // also works (provided earlier)
|
||||
|
||||
scenario = new EngineScenario();
|
||||
scenario.Initialize(SampleRate);
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
@@ -52,18 +50,13 @@ public class Program
|
||||
double drawInterval = 1.0 / DrawFrequency;
|
||||
double lastSpeedUpdateTime = stopwatch.Elapsed.TotalSeconds;
|
||||
|
||||
// Resampling buffer
|
||||
var simBuffer = new List<float>(4096);
|
||||
double readIndex = 0.0;
|
||||
|
||||
// Prime the buffer with a few samples
|
||||
for (int i = 0; i < 4; i++)
|
||||
simBuffer.Add(scenario.Process());
|
||||
|
||||
long totalSimSteps = simBuffer.Count;
|
||||
long totalOutputSamples = 0;
|
||||
|
||||
double lastRealTime = stopwatch.Elapsed.TotalSeconds;
|
||||
const int outputChunk = 256;
|
||||
float[] outputBuf = new float[outputChunk];
|
||||
|
||||
@@ -72,16 +65,22 @@ public class Program
|
||||
window.DispatchEvents();
|
||||
|
||||
double currentRealTime = stopwatch.Elapsed.TotalSeconds;
|
||||
double dtSpeed = currentRealTime - lastSpeedUpdateTime;
|
||||
double dtClock = currentRealTime - lastSpeedUpdateTime;
|
||||
lastSpeedUpdateTime = currentRealTime;
|
||||
|
||||
// Smoothly transition currentSpeed → desiredSpeed
|
||||
double smoothingRate = 8.0; // higher = faster catch‑up
|
||||
currentSpeed += (desiredSpeed - currentSpeed) * (1.0 - Math.Exp(-smoothingRate * dtSpeed));
|
||||
// Smooth simulation speed
|
||||
double speedSmoothing = 8.0;
|
||||
currentSpeed += (desiredSpeed - currentSpeed) * (1.0 - Math.Exp(-speedSmoothing * dtClock));
|
||||
|
||||
// ---------- Generate audio ----------
|
||||
// ---- THROTTLE INPUT ----
|
||||
targetThrottle = Keyboard.IsKeyPressed(Keyboard.Key.W) ? 1.0 : 0.0;
|
||||
currentThrottle += (targetThrottle - currentThrottle) * (1.0 - Math.Exp(-ThrottleSmoothing * dtClock));
|
||||
// Push to engine scenario (if it's an EngineScenario)
|
||||
if (scenario is EngineScenario engine)
|
||||
engine.Throttle = currentThrottle;
|
||||
|
||||
// Generate audio
|
||||
double targetAudioClock = currentRealTime + 0.05;
|
||||
|
||||
while (totalOutputSamples < targetAudioClock * SampleRate && running)
|
||||
{
|
||||
int toGenerate = (int)Math.Min(
|
||||
@@ -103,11 +102,9 @@ public class Program
|
||||
int i0 = (int)readIndex;
|
||||
int i1 = i0 + 1;
|
||||
double frac = readIndex - i0;
|
||||
|
||||
float y0 = simBuffer[Math.Clamp(i0, 0, simBuffer.Count - 1)];
|
||||
float y1 = simBuffer[Math.Clamp(i1, 0, simBuffer.Count - 1)];
|
||||
outputBuf[i] = (float)(y0 + (y1 - y0) * frac);
|
||||
|
||||
readIndex += currentSpeed;
|
||||
|
||||
while (readIndex >= 1.0 && simBuffer.Count > 2)
|
||||
@@ -119,23 +116,23 @@ public class Program
|
||||
|
||||
int accepted = soundEngine.WriteSamples(outputBuf, toGenerate);
|
||||
totalOutputSamples += accepted;
|
||||
|
||||
if (accepted < toGenerate)
|
||||
break;
|
||||
}
|
||||
|
||||
// ---------- Drawing & window title ----------
|
||||
// Drawing & title
|
||||
if (currentRealTime - lastDrawTime >= drawInterval)
|
||||
{
|
||||
double actualSpeed = totalOutputSamples / (currentRealTime * SampleRate);
|
||||
double simTime = totalSimSteps / (double)SampleRate;
|
||||
string toggleHint = isRealTime ? "[Space] slow mo" : "[Space] real time";
|
||||
string throttleHint = Keyboard.IsKeyPressed(Keyboard.Key.W) ? "W held" : "W released";
|
||||
window.SetTitle(
|
||||
$"{toggleHint} Sim: {simTime:F2}s | " +
|
||||
$"Speed: {currentSpeed:F4}x → {desiredSpeed:F4}x | " +
|
||||
$"Actual: {actualSpeed:F2}x"
|
||||
$"{toggleHint} {throttleHint} " +
|
||||
$"Thr: {currentThrottle:F2} " +
|
||||
$"Speed: {currentSpeed:F3}x → {desiredSpeed:F3}x " +
|
||||
$"Act: {actualSpeed:F2}x"
|
||||
);
|
||||
|
||||
window.Clear(Color.Black);
|
||||
scenario.Draw(window);
|
||||
window.Display();
|
||||
@@ -147,22 +144,18 @@ public class Program
|
||||
window.Dispose();
|
||||
}
|
||||
|
||||
// (Mouse wheel, space toggle unchanged)
|
||||
private static void OnMouseWheel(object? sender, MouseWheelScrollEventArgs e)
|
||||
{
|
||||
bool wasRealTime = Math.Abs(desiredSpeed - 1.0) < 1e-6;
|
||||
|
||||
if (e.Delta > 0)
|
||||
desiredSpeed *= ScrollFactor;
|
||||
else if (e.Delta < 0)
|
||||
desiredSpeed /= ScrollFactor;
|
||||
|
||||
desiredSpeed = Math.Clamp(desiredSpeed, MinSpeed, MaxSpeed);
|
||||
|
||||
// Update the remembered slow‑mo speed (unless we are exactly at 1.0)
|
||||
if (!wasRealTime || Math.Abs(desiredSpeed - 1.0) > 1e-6)
|
||||
lastDesiredSpeed = desiredSpeed;
|
||||
|
||||
// Update isRealTime flag
|
||||
isRealTime = Math.Abs(desiredSpeed - 1.0) < 1e-6;
|
||||
}
|
||||
|
||||
@@ -171,15 +164,9 @@ public class Program
|
||||
if (e.Code == Keyboard.Key.Space)
|
||||
{
|
||||
if (isRealTime)
|
||||
{
|
||||
// Switch to the remembered slow speed
|
||||
desiredSpeed = lastDesiredSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Switch back to real time
|
||||
desiredSpeed = 1.0;
|
||||
}
|
||||
isRealTime = !isRealTime;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user