Peoplemon  0.1.0
Peoplemon 3 game source documentation
Snow.cpp
Go to the documentation of this file.
1 #include "Snow.hpp"
2 
3 #include <BLIB/Cameras/2D/Camera2D.hpp>
4 #include <BLIB/Util/Random.hpp>
5 #include <Core/Properties.hpp>
6 
7 namespace core
8 {
9 namespace map
10 {
11 namespace weather
12 {
13 namespace
14 {
15 constexpr float SpawnRate = 450.f;
16 constexpr float FastFallSpeed = -340.f;
17 constexpr float SlowFallSpeed = -100.f;
18 constexpr float GroundTime = -2.f;
19 constexpr float HorizontalAccel = 128.f;
20 constexpr float HorizontalVel = 64.f;
21 constexpr float StopTime = 4.f;
22 constexpr float StopSpeed = 1.f / StopTime;
23 constexpr float RespawnDelay = 2.f;
24 
25 std::size_t deadCount = 0;
26 } // namespace
27 
28 namespace snow
29 {
30 struct Snowflake {
31  glm::vec2 pos;
32  glm::vec2 vel;
33  float height;
34 
35  Snowflake() = default;
36 
37  Snowflake(const sf::FloatRect& area) {
38  pos.x = bl::util::Random::get<float>(area.left - 300.f, area.left + area.width + 300.f);
39  pos.y = bl::util::Random::get<float>(area.top - 300.f, area.top + area.height + 300.f);
40  vel.x = bl::util::Random::get<float>(-HorizontalVel, HorizontalVel);
41  vel.y = bl::util::Random::get<float>(-1.f, 1.f);
42  height = bl::util::Random::get<float>(140.f, 200.f);
43  }
44 };
45 
46 struct GpuSnowflake {
47  glm::vec2 pos;
48  float height;
49  float padding;
50 
51  GpuSnowflake() = default;
52 
54  pos = drop.pos;
55  height = drop.height;
56  return *this;
57  }
58 };
59 
60 struct alignas(8) GlobalShaderInfo {
61  std::uint32_t textureId;
62 };
63 } // namespace snow
64 } // namespace weather
65 } // namespace map
66 } // namespace core
67 
68 namespace bl
69 {
70 namespace pcl
71 {
75 
76 template<>
77 struct RenderConfigMap<Snowflake> {
78  static constexpr std::uint32_t PipelineId = core::Properties::SnowflakePipelineId;
79  static constexpr bool ContainsTransparency = true;
80 
81  static constexpr bool CreateRenderPipeline = true;
82 
83  static constexpr std::initializer_list<std::uint32_t> RenderPassIds =
84  bl::pcl::RenderConfigDefaults<Snowflake>::RenderPassIds;
85 
88  bl::pcl::RenderConfigDescriptorList<bl::rc::ds::TexturePoolFactory,
89  bl::rc::ds::Scene2DFactory,
90  bl::pcl::DescriptorSetFactory<Snowflake, GpuSnowflake>>;
91 
92  static constexpr bool EnableDepthTesting = true;
93  static constexpr VkPrimitiveTopology Topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
94  static constexpr const char* VertexShader = "Resources/Shaders/Particles/snowflake.vert.spv";
95  static constexpr const char* FragmentShader = bl::rc::Config::ShaderIds::Fragment2DSkinnedLit;
96 };
97 } // namespace pcl
98 } // namespace bl
99 
100 namespace core
101 {
102 namespace map
103 {
104 namespace weather
105 {
106 namespace snow
107 {
108 class GravityAffector : public bl::pcl::Affector<Snowflake> {
109 public:
110  GravityAffector(float fallVel)
111  : fallVel(fallVel) {}
112 
113  virtual ~GravityAffector() = default;
114 
115  virtual void update(Proxy& proxy, float dt, float) override {
116  for (Snowflake& flake : proxy.particles()) {
117  if (flake.height > 0.f) {
118  flake.pos += flake.vel * dt;
119  flake.height += fallVel * dt;
120  if (flake.vel.y > 0.f) {
121  flake.vel.x -= HorizontalAccel * dt;
122  if (flake.vel.x < -HorizontalVel) { flake.vel.y = -1.f; }
123  }
124  else {
125  flake.vel.x += HorizontalAccel * dt;
126  if (flake.vel.x > HorizontalVel) { flake.vel.y = 1.f; }
127  }
128 
129  if (flake.height < 0.f) flake.height = -0.001f;
130  }
131  else { flake.height -= dt; }
132  }
133  }
134 
135 private:
136  const float fallVel;
137 };
138 
139 class TimeSink : public bl::pcl::Sink<Snowflake> {
140 public:
142  : time(0.f) {}
143 
144  virtual ~TimeSink() = default;
145 
146  virtual void update(Proxy& proxy, std::span<Snowflake> particles, float dt, float) override {
147  time += dt;
148  for (Snowflake& drop : particles) {
149  if (drop.height <= GroundTime) {
150  proxy.destroy(drop);
151  if (time >= RespawnDelay) { ++deadCount; }
152  }
153  }
154  }
155 
156 private:
157  float time;
158 };
159 
160 class TimeEmitter : public bl::pcl::Emitter<Snowflake> {
161 public:
162  TimeEmitter(bl::rc::RenderTarget& observer, std::size_t target)
163  : observer(observer)
164  , target(target)
165  , residual(0.f) {}
166 
167  virtual ~TimeEmitter() = default;
168 
169  void setTarget(std::size_t t) { target = t; }
170 
171  virtual void update(Proxy& proxy, float dt, float) override {
172  const std::size_t current = proxy.getManager().getParticleCount();
173  if (current < target) {
174  residual += SpawnRate * dt;
175  if (residual >= 1.f || deadCount > 0) {
176  const std::size_t maxSpawn = target - current;
177  const std::size_t toSpawn =
178  std::min(static_cast<std::size_t>(std::floor(residual)) + deadCount, maxSpawn);
179  residual -= static_cast<float>(toSpawn);
180 
181  bl::cam::Camera2D* cam = observer.getCurrentCamera<bl::cam::Camera2D>();
182  if (!cam) { return; }
183  const sf::FloatRect area = cam->getVisibleArea();
184  for (std::size_t i = 0; i < toSpawn; ++i) { proxy.emit(area); }
185  }
186  }
187  }
188 
189 private:
190  bl::rc::RenderTarget& observer;
191  std::size_t target;
192  float residual;
193 };
194 
195 } // namespace snow
196 
197 Snow::Snow(bool hard, bool thunder)
198 : engine(nullptr)
199 , _type(hard ? (thunder ? Weather::HardSnowThunder : Weather::HardSnow) :
200  (thunder ? Weather::LightSnowThunder : Weather::LightSnow))
201 , targetParticleCount(hard ? Properties::HardSnowParticleCount() :
202  Properties::LightSnowParticleCount())
203 , fallSpeed(hard ? FastFallSpeed : SlowFallSpeed)
204 , stopFactor(-1.f)
205 , thunder(thunder, hard) {}
206 
208  stop();
209  if (engine) { engine->particleSystem().removeUniqueSystem<snow::Snowflake>(); }
210 }
211 
212 Weather::Type Snow::type() const { return _type; }
213 
214 void Snow::start(bl::engine::Engine& e, bl::rc::RenderTarget& renderTarget, Map& map) {
215  engine = &e;
216  deadCount = 0;
217 
218  const auto sampler = e.renderer().vulkanState().samplerCache.noFilterBorderClamped();
219  snowTxtr = e.renderer().texturePool().getOrLoadTexture(Properties::SnowFlakeFile(), sampler);
220 
221  particles = &e.particleSystem().getUniqueSystem<snow::Snowflake>();
222 
223  emitter = particles->addEmitter<snow::TimeEmitter>(renderTarget, targetParticleCount);
224  particles->addAffector<snow::GravityAffector>(fallSpeed);
225  particles->addSink<snow::TimeSink>();
226  particles->addToScene(renderTarget.getCurrentScene());
227 
228  particles->getRenderer().getGlobals().textureId = snowTxtr.id();
229  particles->getRenderer().getComponent()->makeSprite(snowTxtr);
230  for (auto& v : particles->getRenderer().getComponent()->vertexBuffer.vertices()) {
231  v.pos.z = map.getMinDepth();
232  }
233 }
234 
235 void Snow::stop() {
236  stopFactor = 0.f;
237  thunder.stop();
238 }
239 
240 bool Snow::stopped() const { return particles && particles->getParticleCount() == 0; }
241 
242 void Snow::update(float dt) {
243  if (stopFactor >= 0.f) {
244  stopFactor = std::min(stopFactor + StopSpeed * dt, 1.f);
245  emitter->setTarget(
246  targetParticleCount -
247  static_cast<unsigned int>(static_cast<float>(targetParticleCount) * stopFactor));
248  if (stopFactor >= 0.8f) {
249  stopFactor = -1.f;
250  emitter->setTarget(0);
251  }
252  }
253 }
254 
255 } // namespace weather
256 } // namespace map
257 } // namespace core
Core classes and functionality for both the editor and game.
core::map::weather::fog::GlobalShaderInfo GlobalShaderInfo
Definition: Fog.cpp:79
core::map::weather::snow::Snowflake Snowflake
Definition: Snow.cpp:72
core::map::weather::snow::GpuSnowflake GpuSnowflake
Definition: Snow.cpp:73
The primary map class that represents a usable map in the game.
Definition: Map.hpp:49
float getMinDepth() const
Returns the maximum depth possible for this map. Maximum is always 0.f. Minimum is negative,...
Definition: Map.cpp:775
Parent weather system for maps. Manages active weather.
Definition: Weather.hpp:32
Type
The type of weather.
Definition: Weather.hpp:38
Wrapper around bl::engine::Configuration. Provides application configuration in variables that may be...
Definition: Properties.hpp:28
static constexpr std::uint32_t SnowflakePipelineId
Definition: Properties.hpp:137
static const std::string & SnowFlakeFile()
Definition: Properties.cpp:401
Snowflake(const sf::FloatRect &area)
Definition: Snow.cpp:37
GpuSnowflake & operator=(const Snowflake &drop)
Definition: Snow.cpp:53
bl::pcl::RenderConfigDescriptorList< bl::rc::ds::TexturePoolFactory, bl::rc::ds::Scene2DFactory, bl::pcl::DescriptorSetFactory< Snowflake, GpuSnowflake > > DescriptorSets
Definition: Snow.cpp:90
virtual void update(Proxy &proxy, float dt, float) override
Definition: Snow.cpp:115
virtual void update(Proxy &proxy, std::span< Snowflake > particles, float dt, float) override
Definition: Snow.cpp:146
virtual void update(Proxy &proxy, float dt, float) override
Definition: Snow.cpp:171
void setTarget(std::size_t t)
Definition: Snow.cpp:169
TimeEmitter(bl::rc::RenderTarget &observer, std::size_t target)
Definition: Snow.cpp:162
virtual void stop() override
Stops the snow.
Definition: Snow.cpp:235
virtual Weather::Type type() const override
One of LightSnow, LightSnowThunder, HardSnow, HardSnowThunder.
Definition: Snow.cpp:212
virtual bool stopped() const override
Returns true when no snow is left after a call to stop()
Definition: Snow.cpp:240
Snow(bool hard, bool thunder)
Create snowy weather.
Definition: Snow.cpp:197
virtual void start(bl::engine::Engine &engine, bl::rc::RenderTarget &renderTarget, Map &map) override
Start the snow.
Definition: Snow.cpp:214
virtual void update(float dt) override
Updates all the flakes and spawns more.
Definition: Snow.cpp:242
virtual ~Snow()
Destroy the Snow object.
Definition: Snow.cpp:207
void stop()
Prevents further thunder and fades out current strike if present.
Definition: Thunder.cpp:42