feat(lighting): flicker proporcional al radi amb overrides per emissor
This commit is contained in:
1 parent
3a42c7958a
commit
2272d3a37a
13 files changed
+298
-150
No files matched your search
+48
-22
@@ -78,6 +78,52 @@ namespace Map {
|
||||
};
|
||||
}
|
||||
|
||||
// Llegeix el sub-bloc opcional `flicker_params:` d'un emissor de
|
||||
// sala. Camps individuals — qualsevol absent conserva el valor
|
||||
// del global (`Lighting::flickerConfig()`) o de la capa que ho
|
||||
// precedeixi (tipus / sala).
|
||||
void readFlickerOverrides(const fkyaml::node& fp, RoomEmitterOverride& ov) {
|
||||
if (fp.contains("wave_amplitude_ratio")) { ov.flicker_wave_amplitude_ratio = fp["wave_amplitude_ratio"].get_value<float>(); }
|
||||
if (fp.contains("wave_frequency_hz")) { ov.flicker_wave_frequency_hz = fp["wave_frequency_hz"].get_value<float>(); }
|
||||
if (fp.contains("noise_amplitude_ratio")) { ov.flicker_noise_amplitude_ratio = fp["noise_amplitude_ratio"].get_value<float>(); }
|
||||
if (fp.contains("noise_frequency_hz")) { ov.flicker_noise_frequency_hz = fp["noise_frequency_hz"].get_value<float>(); }
|
||||
}
|
||||
|
||||
// Llegeix una entrada del mapping `lighting.emitters.<tipus>` en
|
||||
// qualsevol de les seves 3 formes (bool curt o mapping detallat).
|
||||
// Extret per mantenir `loadLightingBlock` sota el llindar de
|
||||
// complexitat cognitiva de clang-tidy.
|
||||
auto readEmitterEntry(const fkyaml::node& val) -> RoomEmitterOverride {
|
||||
RoomEmitterOverride ov;
|
||||
if (val.is_boolean()) {
|
||||
ov.enabled = val.get_value<bool>();
|
||||
return ov;
|
||||
}
|
||||
if (!val.is_mapping()) { return ov; }
|
||||
ov.enabled = true;
|
||||
if (val.contains("radius")) { ov.radius = val["radius"].get_value<int>(); }
|
||||
if (val.contains("flicker")) { ov.flicker = val["flicker"].get_value<bool>(); }
|
||||
if (val.contains("color")) { ov.color = parseColorTriplet(val["color"]); }
|
||||
if (val.contains("offset")) { ov.offset = parseIntPair(val["offset"]); }
|
||||
if (val.contains("flicker_params")) { readFlickerOverrides(val["flicker_params"], ov); }
|
||||
return ov;
|
||||
}
|
||||
|
||||
// Llegeix la subclau `mode:` del bloc `lighting:` i actualitza
|
||||
// `lighting_mode`. Avisa via Log si el valor no és reconegut.
|
||||
// Extret de `loadLightingBlock` per la mateixa raó.
|
||||
void readLightingMode(const fkyaml::node& lighting) {
|
||||
if (!lighting.contains("mode")) { return; }
|
||||
const auto MODE_STR = lighting["mode"].get_value<std::string>();
|
||||
if (MODE_STR == "additive") {
|
||||
lighting_mode = Lighting::Mode::ADDITIVE;
|
||||
} else if (MODE_STR == "subtractive") {
|
||||
lighting_mode = Lighting::Mode::SUBTRACTIVE;
|
||||
} else {
|
||||
Log::warn("Map", "lighting.mode '{}' desconegut — s'usa subtractive", MODE_STR);
|
||||
}
|
||||
}
|
||||
|
||||
// Llegeix el bloc opcional `lighting:` del YAML d'una sala i
|
||||
// actualitza `light_level`, `lighting_mode` i el mapping
|
||||
// `g_room_emitters`. Idempotent: cada `Map::loadFrom` reseteja
|
||||
@@ -91,32 +137,12 @@ namespace Map {
|
||||
if (lighting.contains("level")) {
|
||||
light_level = lighting["level"].get_value<float>();
|
||||
}
|
||||
if (lighting.contains("mode")) {
|
||||
const auto MODE_STR = lighting["mode"].get_value<std::string>();
|
||||
if (MODE_STR == "additive") {
|
||||
lighting_mode = Lighting::Mode::ADDITIVE;
|
||||
} else if (MODE_STR == "subtractive") {
|
||||
lighting_mode = Lighting::Mode::SUBTRACTIVE;
|
||||
} else {
|
||||
Log::warn("Map", "lighting.mode '{}' desconegut — s'usa subtractive", MODE_STR);
|
||||
}
|
||||
}
|
||||
readLightingMode(lighting);
|
||||
if (!lighting.contains("emitters") || !lighting["emitters"].is_mapping()) { return; }
|
||||
const auto& em = lighting["emitters"];
|
||||
for (auto it = em.begin(); it != em.end(); ++it) {
|
||||
const auto KEY = normalizeEmitterKey(it.key().get_value<std::string>());
|
||||
const auto& val = it.value();
|
||||
RoomEmitterOverride ov;
|
||||
if (val.is_boolean()) {
|
||||
ov.enabled = val.get_value<bool>();
|
||||
} else if (val.is_mapping()) {
|
||||
ov.enabled = true;
|
||||
if (val.contains("radius")) { ov.radius = val["radius"].get_value<int>(); }
|
||||
if (val.contains("flicker")) { ov.flicker = val["flicker"].get_value<bool>(); }
|
||||
if (val.contains("color")) { ov.color = parseColorTriplet(val["color"]); }
|
||||
if (val.contains("offset")) { ov.offset = parseIntPair(val["offset"]); }
|
||||
}
|
||||
g_room_emitters[KEY] = ov;
|
||||
g_room_emitters[KEY] = readEmitterEntry(it.value());
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -99,6 +99,14 @@ namespace Map {
|
||||
// sprite (píxels enters; Y creix avall). `nullopt` → conservar
|
||||
// l'offset del tipus (default [0, 0]). Forma YAML: `offset: [x, y]`.
|
||||
std::optional<std::array<int, 2>> offset;
|
||||
// Overrides parcials per cada camp del `FlickerConfig` (ràtio
|
||||
// d'amplitud i freqüència del wave + noise). `nullopt` → no
|
||||
// toca aquell camp (conserva el del tipus, que al seu torn pot
|
||||
// ser el global). Forma YAML: `flicker_params: { wave_frequency_hz: 1.0, ... }`.
|
||||
std::optional<float> flicker_wave_amplitude_ratio;
|
||||
std::optional<float> flicker_wave_frequency_hz;
|
||||
std::optional<float> flicker_noise_amplitude_ratio;
|
||||
std::optional<float> flicker_noise_frequency_hz;
|
||||
};
|
||||
|
||||
// Consulta l'override de sala per a un tipus d'entitat (clau singular,
|
||||
|
||||
Reference in new issue
Block a user