feat(lighting): flicker proporcional al radi amb overrides per emissor

This commit is contained in:
JailDesigner committed 2026-05-13 19:38:34 +02:00
1 parent 3a42c7958a
commit 2272d3a37a
13 files changed
+298 -150

No files matched your search

+48 -22
View File
@@ -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