3 #include <BLIB/Math.hpp>
4 #include <BLIB/Render/Primitives/Color.hpp>
5 #include <BLIB/Util/Random.hpp>
16 constexpr
float AdjustSpeed = 30.f;
17 constexpr std::size_t GameBufferExtra = 0;
18 constexpr std::size_t EditorBufferExtra = 64;
19 constexpr
float ThunderDuration = 1.3f;
30 , targetWeatherModifier(0)
31 , weatherResidual(0.f)
32 , thunderTime(-1.f) {}
35 rawLights.push_back(light);
36 addLightToScene(light);
39 void LightingSystem::addLightToScene(
const Light& light) {
41 activeLights.emplace_back(sceneLighting->addLight(
42 glm::vec2(
static_cast<float>(light.
position.x),
static_cast<float>(light.
position.y)),
43 static_cast<float>(light.
radius),
44 glm::vec3(
static_cast<float>(light.
color.x) / 255.f,
45 static_cast<float>(light.
color.y) / 255.f,
46 static_cast<float>(light.
color.z) / 255.f)));
51 rawLights[handle] = light;
54 bl::rc::lgt::Light2D& l = activeLights[handle];
56 glm::vec2(
static_cast<float>(light.
position.x),
static_cast<float>(light.
position.y)));
57 l.setRadius(
static_cast<float>(light.
radius));
58 l.setColor(glm::vec3(
static_cast<float>(light.
color.x) / 255.f,
59 static_cast<float>(light.
color.y) / 255.f,
60 static_cast<float>(light.
color.z) / 255.f));
66 unsigned long cdist = 10000000;
68 for (
unsigned int i = 0; i < rawLights.size(); ++i) {
69 const unsigned long dist = bl::math::magnitudeSquared(rawLights[i].position - position);
70 const unsigned int r = rawLights[i].radius;
71 if (dist < cdist && dist < r * r) {
83 rawLights.erase(rawLights.begin() + handle);
86 activeLights[handle].removeFromScene();
87 activeLights.erase(activeLights.begin() + handle);
94 minLevel = std::min(lowLightLevel, highLightLevel);
95 maxLevel = std::max(lowLightLevel, highLightLevel);
96 levelRange = maxLevel - minLevel;
108 sceneLighting = &lighting;
109 levelRange = maxLevel - minLevel;
111 activeLights.reserve(rawLights.size() +
113 for (
const auto& light : rawLights) { addLightToScene(light); }
114 for (
auto& handle : activeLights) { handle.setColor(glm::vec3(0.f)); }
115 lightsActive =
false;
117 updateAmbientLighting();
128 levelRange = maxLevel - minLevel;
130 for (
auto& light : activeLights) { light.removeFromScene(); }
131 activeLights.clear();
135 if (weatherModifier != targetWeatherModifier) {
136 weatherResidual += AdjustSpeed * dt;
137 const float p = std::floor(weatherResidual);
139 weatherResidual -= p;
140 if (targetWeatherModifier > weatherModifier) {
141 weatherModifier +=
static_cast<int>(p);
142 if (weatherModifier > targetWeatherModifier) {
143 weatherModifier = targetWeatherModifier;
144 weatherResidual = 0.f;
148 weatherModifier -=
static_cast<int>(p);
149 if (weatherModifier < targetWeatherModifier) {
150 weatherModifier = targetWeatherModifier;
151 weatherResidual = 0.f;
159 Light* light = &rawLights.front();
161 for (
auto& handle : activeLights) {
162 handle.setColor(glm::vec3(
static_cast<float>(light->
color.x) / 255.f,
163 static_cast<float>(light->
color.y) / 255.f,
164 static_cast<float>(light->
color.z) / 255.f));
169 lightsActive =
false;
170 for (
auto& handle : activeLights) { handle.setColor(glm::vec3(0.f)); }
173 if (thunderTime >= 0.f) {
175 if (thunderTime >= ThunderDuration) { thunderTime = -1.f; }
178 updateAmbientLighting();
181 void LightingSystem::updateAmbientLighting() {
183 const std::uint8_t ambient = computeAmbient();
184 float a =
static_cast<float>(255 - ambient) / 255.f;
185 if (thunderTime >= 0.f) {
186 if (thunderTime <= 0.5f) {
187 const float x = thunderTime - 0.2f;
188 const float m = -3.92f * x * x + 1.88f;
192 const float x = (thunderTime - 0.5f) - 0.2f;
193 const float m = -2.16f * x * x + 1.78f;
200 sceneLighting->setAmbientLight(color);
204 std::uint8_t LightingSystem::computeAmbient()
const {
205 const float preambient = 255.f - (
static_cast<float>(minLevel) + levelRange * sunlightFactor);
206 return std::min(std::max(0,
static_cast<int>(preambient) + weatherModifier), 255);
212 const float n = 0.7f;
213 sunlightFactor = 1.f - (0.5 * std::cos(3.1415926 * x / 720) + 0.5) *
214 ((1 - n) * (720 - x) * (720 - x) / 518400 + n);
216 else { sunlightFactor = 1.f; }
220 switch (event.
type) {
258 targetWeatherModifier = 0;
Core classes and functionality for both the editor and game.
Basic event for when the game time changes.
const system::Clock::Time & newTime
A reference to the new time.
Fired when weather starts.
const map::Weather::Type type
The type of weather that started.
Fired when weather stops.
Fired when thunder happens.
Represents a renderable light in a Map.
std::uint16_t Handle
Handle representing a light in the map.
std::uint8_t getMaxLightLevel() const
Returns the maximum ambient light level of this map.
void setColorTint(const glm::vec3 &tint)
Sets a color tint to apply to the ambient lighting.
std::uint8_t getMinLightLevel() const
Returns the minimum ambient light level of this map.
LightingSystem()
Initializes the lighting system with no lights.
const Light & getLight(Handle handle) const
Returns the value of the light with the given handle. Invalid handles return a default value (a light...
void addLight(const Light &light)
Adds a light to the map and to the persistent map file.
void update(float dt)
Updates the lighting system.
void adjustForSunlight(bool adjust)
Set whether or not the light level is adjusted based on time of day. If not adjusting for sunlight th...
void unsubscribe()
Unsubscribes the lighting system from the event dispatcher.
void setAmbientLevel(std::uint8_t lowLightLevel, std::uint8_t highLightLevel)
The ambient light band. 0 is full darkness and 255 is full brightness.
void updateLight(Handle handle, const Light &value)
Updates the light with the given handle to the new information.
bool lightsAreOn() const
Returns whether lights are being shown or not based on how dark it is.
Handle getClosestLight(const sf::Vector2i &position)
Returns a handle to the light closest to the given position.
static constexpr Handle None
Special handle indicating that no light is referenced.
void removeLight(Handle light)
Remove the given light from the system and optionally persist the removal.
void activate(bl::rc::lgt::Scene2DLighting &sceneLighting)
Adds all lights into the scene.
void subscribe()
Subscribes the lighting system to time events for ambient light level.
virtual void observe(const event::TimeChange &timeChange) override
Updates the light level based on the new current time.
bool adjustsForSunlight() const
Returns whether or not this map is adjusted for time of day.
void clear()
Clears all lights from the map, including the persisted light data.
@ HardSnowThunder
Hard snow with thunder.
@ Sunny
A very sunny day with pulsating light.
@ ThinFog
Thin fog covers the area.
@ SandStorm
A sandstorm ravages you.
@ HardRain
Hard rain with no thunder.
@ HardRainThunder
Hard rain with thunder.
@ LightRainThunder
Light rain with thunder.
@ LightSnowThunder
Light snow with thunder.
@ LightRain
Light rain with no thunder.
@ ThickFog
Thick fog obscures everything.
@ LightSnow
Light snow with no thunder.
@ HardSnow
Hard snow with no thunder.
static int LightRainLightModifier()
static int SunnyLightModifier()
static int HardRainLightModifier()
static int HardSnowLightModifier()
static int SandstormLightModifier()
static int ThickFogLightModifier()
static int ThinFogLightModifier()
static int LightSnowLightModifier()
unsigned int minute
Current minute of the hour. In range [0, 59].
unsigned int hour
Current hour of the day, in range [0, 23].