Load engines from TOML and improve scenario audio and carb tuning

Migrate 32 engine definitions into validated startup-loaded TOML files and separate configuration and snapshots from scenario assembly. Add camera-based stereo propagation from shared pipe geometry, preserve exhaust character, tune carburetor mixtures and idle, use ignition cuts for carb engines, and support returning to the scenario menu.

Validation: full Windows build and all 14 CTest checks passed.
This commit is contained in:
max
2026-10-24 03:24:35 +02:00
parent 5607dcf2b5
commit bf8621ad39
82 changed files with 24084 additions and 648 deletions

View File

@@ -1,4 +1,5 @@
#include "FluidSim/Scenario.hpp"
#include "FluidSim/ScenarioCatalog.hpp"
#include "FluidSim/TwoStrokeScenario.hpp"
#include <algorithm>
#include <cmath>
@@ -65,9 +66,13 @@ struct Metrics {
}
};
template <class Scenario>
void capture(const std::string &prefix, int frames, float pedal, OutdoorScene scene, TwoStrokeConfig config, PipeSolver solver, float fixed_rpm, float warmup) {
void capture(const std::string &prefix, int frames, float pedal, OutdoorScene scene, TwoStrokeConfig config, PipeSolver solver, float fixed_rpm, float warmup, const ScenarioExample* example=nullptr) {
std::unique_ptr<Scenario> s;
if constexpr (std::is_same_v<Scenario, TwoStrokeScenario>) s = std::make_unique<Scenario>(44100, config);
else if constexpr (std::is_same_v<Scenario, FourStrokeScenario>) {
if(example) s=std::make_unique<Scenario>(44100,*example);
else s=std::make_unique<Scenario>();
}
else s = std::make_unique<Scenario>();
s->set_pipe_solver(solver);
s->throttle = pedal;
@@ -101,6 +106,7 @@ void capture(const std::string &prefix, int frames, float pedal, OutdoorScene sc
} // namespace
int main(int argc, char **argv) {
try {
std::string example_id;
std::string scenario = "twin", prefix = "build/audio/twin", scene = "wall";
float seconds = 6, pedal = 1, fixed_rpm = 0, warmup = 0;
TwoStrokeConfig config;
@@ -110,7 +116,8 @@ int main(int argc, char **argv) {
if (i + 1 >= argc)
throw std::runtime_error("missing option value");
std::string value = argv[++i];
if (key == "--scenario")
if(key=="--example") example_id=value;
else if (key == "--scenario")
scenario = value;
else if (key == "--out")
prefix = value;
@@ -153,7 +160,14 @@ int main(int argc, char **argv) {
if (!std::filesystem::path(prefix).parent_path().empty())
std::filesystem::create_directories(std::filesystem::path(prefix).parent_path());
const int frames = int(std::lround(seconds * 44100));
if (scenario == "twin")
const auto examples=scenario_examples();
if(!example_id.empty()) {
const auto example=std::find_if(examples.begin(),examples.end(),[&](const auto& e){return e.id==example_id;});
if(example==examples.end()) throw std::runtime_error("unknown example: "+example_id);
if(example->kind==ScenarioKind::TwoStroke)
capture<TwoStrokeScenario>(prefix,frames,pedal,selected,example->two,solver,fixed_rpm,warmup);
else capture<FourStrokeScenario>(prefix,frames,pedal,selected,config,solver,fixed_rpm,warmup,&*example);
} else if (scenario == "twin")
capture<FourStrokeTwinScenario>(prefix, frames, pedal, selected, config, solver, fixed_rpm, warmup);
else if (scenario == "b205")
capture<SaabB205Scenario>(prefix, frames, pedal, selected, config, solver, fixed_rpm, warmup);