载入中...
搜索中...
未找到
Weather.cpp
浏览该文件的文档.
1#include "weather/Weather.h"
2
3#include "graphics/Graphics.h"
4#include "graphics/Material.h"
5#include "graphics/Mesh.h"
6#include "graphics/Shader.h"
8
9#include <cmath>
10#include <cstdint>
11#include <cstring>
12#include <string>
13#include <vector>
14
15#include <simplesquirrel/simplesquirrel.hpp>
16
17#include "weather/shaders/weather_vert_spv.inc"
18#include "weather/shaders/weather_frag_spv.inc"
19#include "weather/shaders/bolt_vert_spv.inc"
20#include "weather/shaders/bolt_frag_spv.inc"
21
22namespace eve::weather {
23
24namespace {
25
26// ---- tiny deterministic RNG (no dependency on <random>) ----
27struct Lcg {
28 uint32_t s = 0x9e3779b9u;
29 uint32_t next() {
30 s = s * 1664525u + 1013904223u;
31 return s;
32 }
33 float unit() { return float(next() % 10000u) / 9999.f; } // [0,1]
34 float range(float a, float b) { return a + (b - a) * unit(); }
35};
36
37constexpr int kRainCount = 320;
38constexpr int kSnowCount = 260;
39constexpr int kBoltCount = 4;
40
41constexpr float kBoxXZ = 26.f; // half extent on X/Z
42constexpr float kBoxY = 20.f; // fall band height
43
44// Push-constant slots are fixed and must match the shaders and
45// declareWeatherParams(): 0=time 1=windX 2=windZ 3=speed 4=length 5=width
46// 6=intensity 7..9=fog rgb 10=fogDensity 11=flash.
47
48// ---------------------------------------------------------------------------
49// Texture generation
50// ---------------------------------------------------------------------------
51
52// Vertical rain streak: bright core, alpha falloff toward the edges/ends.
53void genRainTexture(std::vector<uint8_t> &rgba) {
54 const int w = 8, h = 32;
55 rgba.resize(size_t(w) * h * 4);
56 for (int y = 0; y < h; ++y) {
57 const float v = (float(y) + 0.5f) / float(h); // 0 top -> 1 bottom
58 const float endFade = 1.f - 2.f * std::fabs(v - 0.5f); // 0 at ends, 1 center
59 for (int x = 0; x < w; ++x) {
60 const float u = (float(x) + 0.5f) / float(w);
61 const float edge = 1.f - 2.f * std::fabs(u - 0.5f); // 0 at sides
62 const float alpha = std::pow(edge, 2.f) * std::pow(endFade, 2.5f);
63 const int i = (y * w + x) * 4;
64 rgba[i + 0] = 255;
65 rgba[i + 1] = 250;
66 rgba[i + 2] = 255;
67 rgba[i + 3] = uint8_t(std::min(255.f, alpha * 255.f));
68 }
69 }
70}
71
72// Soft round snowflake.
73void genSnowTexture(std::vector<uint8_t> &rgba) {
74 const int w = 16, h = 16;
75 rgba.resize(size_t(w) * h * 4);
76 const float cx = (float(w) - 1.f) * 0.5f;
77 const float cy = (float(h) - 1.f) * 0.5f;
78 for (int y = 0; y < h; ++y) {
79 for (int x = 0; x < w; ++x) {
80 const float dx = (float(x) - cx) / cx;
81 const float dy = (float(y) - cy) / cy;
82 const float r = std::sqrt(dx * dx + dy * dy);
83 float alpha = 1.f - r;
84 if (alpha < 0.f) alpha = 0.f;
85 alpha = std::pow(alpha, 2.2f);
86 const int i = (y * w + x) * 4;
87 rgba[i + 0] = 255;
88 rgba[i + 1] = 255;
89 rgba[i + 2] = 255;
90 rgba[i + 3] = uint8_t(std::min(255.f, alpha * 255.f));
91 }
92 }
93}
94
95// ---------------------------------------------------------------------------
96// Mesh builders
97// ---------------------------------------------------------------------------
98
99// A field of billboarded quads. Each quad shares an anchor in inPos; inUV
100// encodes the local offset. `count` quads, `len` = quad height, `width` = width.
101graphics::Mesh *buildFieldMesh(graphics::Graphics *gfx, Lcg &rng, int count, float len,
102 float width) {
103 (void)len;
104 (void)width;
105 const int vertCount = count * 4;
106 const int idxCount = count * 6;
107 std::vector<float> pos(vertCount * 3);
108 std::vector<float> nrm(vertCount * 3, 0.f);
109 std::vector<float> uv(vertCount * 2);
110 std::vector<uint32_t> idx(idxCount);
111
112 for (int i = 0; i < count; ++i) {
113 const float ax = rng.range(-kBoxXZ, kBoxXZ);
114 const float ay = rng.range(0.f, kBoxY);
115 const float az = rng.range(-kBoxXZ, kBoxXZ);
116 const int v0 = i * 4;
117 const int b = v0 * 3, t = v0 * 2;
118
119 // bottom-left / top-left / top-right / bottom-right (uv-driven billboard).
120 pos[b + 0] = ax; pos[b + 1] = ay; pos[b + 2] = az;
121 pos[b + 3] = ax; pos[b + 4] = ay; pos[b + 5] = az;
122 pos[b + 6] = ax; pos[b + 7] = ay; pos[b + 8] = az;
123 pos[b + 9] = ax; pos[b + 10] = ay; pos[b + 11] = az;
124
125 nrm[b + 1] = nrm[b + 4] = nrm[b + 7] = nrm[b + 10] = 1.f;
126
127 // uv.x = horizontal offset, uv.y = vertical offset (in [0,1]).
128 uv[t + 0] = -0.5f; uv[t + 1] = 0.f;
129 uv[t + 2] = -0.5f; uv[t + 3] = 1.f;
130 uv[t + 4] = 0.5f; uv[t + 5] = 1.f;
131 uv[t + 6] = 0.5f; uv[t + 7] = 0.f;
132
133 const uint32_t base = uint32_t(v0);
134 idx[i * 6 + 0] = base + 0;
135 idx[i * 6 + 1] = base + 1;
136 idx[i * 6 + 2] = base + 2;
137 idx[i * 6 + 3] = base + 0;
138 idx[i * 6 + 4] = base + 2;
139 idx[i * 6 + 5] = base + 3;
140 }
141
142 return gfx->newMeshFromArrays(pos.data(), nrm.data(), uv.data(), vertCount, idx.data(),
143 idxCount);
144}
145
146struct Pt {
147 float x = 0, y = 0, z = 0;
148};
149
150// Build a jagged lightning bolt as a tapered quad strip plus short branches.
151graphics::Mesh *buildBoltMesh(graphics::Graphics *gfx, Lcg &rng, Pt top, Pt ground) {
152 std::vector<Pt> pts;
153 // Main trunk with recursive midpoint displacement.
154 const int segs = 24;
155 pts.push_back(top);
156 float y = top.y;
157 float stepY = (top.y - ground.y) / float(segs);
158 for (int i = 1; i < segs; ++i) {
159 y -= stepY;
160 float f = float(i) / float(segs);
161 float jitter = (1.f - f) * 0.9f; // more violent near the top
162 Pt p;
163 p.x = ground.x + (top.x - ground.x) * (1.f - f) + rng.range(-jitter, jitter) * 1.2f;
164 p.y = y;
165 p.z = ground.z + (top.z - ground.z) * (1.f - f) + rng.range(-jitter, jitter) * 1.2f;
166 pts.push_back(p);
167 }
168 pts.push_back(ground);
169
170 // One branch from the upper third.
171 std::vector<Pt> branch;
172 int bStart = int(float(segs) * 0.35f);
173 branch.push_back(pts[bStart]);
174 Pt bp = pts[bStart];
175 for (int i = 1; i <= 8; ++i) {
176 float f = float(i) / 8.f;
177 bp.x += rng.range(-0.5f, 0.5f);
178 bp.y -= (pts[bStart].y - ground.y) * 0.12f;
179 bp.z += rng.range(-0.5f, 0.5f);
180 branch.push_back(bp);
181 }
182
183 std::vector<Pt> all;
184 auto emitStrip = [&](const std::vector<Pt> &path, float wTop, float wBottom) {
185 const int n = int(path.size()) - 1;
186 for (int i = 0; i < n; ++i) {
187 Pt a = path[i], b = path[i + 1];
188 // Side vector (perpendicular to the segment in the XZ plane).
189 float dx = b.x - a.x, dz = b.z - a.z;
190 float len = std::sqrt(dx * dx + dz * dz) + 1e-4f;
191 float sx = -dz / len, sz = dx / len;
192 float w = wBottom + (wTop - wBottom) * (float(i) / float(n));
193 Pt p0 = {a.x + sx * w, a.y, a.z + sz * w};
194 Pt p1 = {a.x - sx * w, a.y, a.z - sz * w};
195 Pt p2 = {b.x - sx * w, b.y, b.z - sz * w};
196 Pt p3 = {b.x + sx * w, b.y, b.z + sz * w};
197 all.push_back(p0);
198 all.push_back(p1);
199 all.push_back(p2);
200 all.push_back(p3);
201 }
202 };
203
204 const float wMain = 0.07f;
205 emitStrip(pts, wMain, wMain * 0.15f);
206 emitStrip(branch, wMain * 0.8f, wMain * 0.15f);
207
208 const int vertCount = int(all.size());
209 const int idxCount = vertCount / 4 * 6;
210 std::vector<float> pos(vertCount * 3);
211 std::vector<float> nrm(vertCount * 3, 0.f);
212 std::vector<float> uv(vertCount * 2, 0.f);
213 std::vector<uint32_t> idx(idxCount);
214
215 for (int i = 0; i < vertCount; ++i) {
216 pos[i * 3 + 0] = all[i].x;
217 pos[i * 3 + 1] = all[i].y;
218 pos[i * 3 + 2] = all[i].z;
219 nrm[i * 3 + 1] = 1.f;
220 uv[i * 2 + 1] = float(i / 4) * 0.25f;
221 }
222 for (int q = 0; q < vertCount / 4; ++q) {
223 const uint32_t base = uint32_t(q * 4);
224 idx[q * 6 + 0] = base + 0;
225 idx[q * 6 + 1] = base + 1;
226 idx[q * 6 + 2] = base + 2;
227 idx[q * 6 + 3] = base + 0;
228 idx[q * 6 + 4] = base + 2;
229 idx[q * 6 + 5] = base + 3;
230 }
231
232 return gfx->newMeshFromArrays(pos.data(), nrm.data(), uv.data(), vertCount, idx.data(),
233 idxCount);
234}
235
236} // namespace
237
238// ---------------------------------------------------------------------------
239
242 bool built = false;
243 float time = 0.f;
244
245 // state
246 int preset = 0; // index into kPresetNames
247 float intensity = 0.f; // 0..1
248 float intensityCur = 0.f;
249 float windSpeed = 0.f;
250 float windDirDeg = 0.f;
251 bool lightningEnabled = true;
252 float flash = 0.f;
253 float flashTimer = 0.f;
254 float nextStrike = 4.f;
255
256 // mood
257 float skyR = 0.45f, skyG = 0.53f, skyB = 0.62f;
258 float sunIntensity = 1.f;
259 float fogR = 0.55f, fogG = 0.58f, fogB = 0.62f;
260 float fogDensity = 0.004f;
261
262 // renderables
265 std::vector<graphics::Renderable3D *> bolts;
268 std::vector<graphics::Material *> boltMats;
269 int activeBolt = -1;
270 float boltLife = 0.f;
271 bool boltOnceFired = false;
272
273 Lcg rng;
274};
275
276const char *const Weather::kPresetNames[] = {"clear", "drizzle", "rain",
277 "storm", "snow", "fog"};
278const int Weather::kPresetCount = 6;
279
280Weather::Weather() : impl_(new Impl()) {}
281
282Weather::~Weather() { delete impl_; }
283
284// ---------------------------------------------------------------------------
285// Private setup
286// ---------------------------------------------------------------------------
287
288namespace {
289void pushWeatherParams(graphics::Material *mat, float time, float windX, float windZ,
290 float speed, float length, float width, float intensity,
291 float fogR, float fogG, float fogB, float fogDensity, float flash) {
292 mat->setFloat("uTime", time);
293 mat->setFloat("uWindX", windX);
294 mat->setFloat("uWindZ", windZ);
295 mat->setFloat("uSpeed", speed);
296 mat->setFloat("uLength", length);
297 mat->setFloat("uWidth", width);
298 mat->setFloat("uIntensity", intensity);
299 mat->setFloat("uFogR", fogR);
300 mat->setFloat("uFogG", fogG);
301 mat->setFloat("uFogB", fogB);
302 mat->setFloat("uFogDensity", fogDensity);
303 mat->setFloat("uFlash", flash);
304}
305
306// Declare the push-constant slots on a shader in the exact order above.
307void declareWeatherParams(graphics::Shader *shader) {
308 shader->declareFloat("uTime");
309 shader->declareFloat("uWindX");
310 shader->declareFloat("uWindZ");
311 shader->declareFloat("uSpeed");
312 shader->declareFloat("uLength");
313 shader->declareFloat("uWidth");
314 shader->declareFloat("uIntensity");
315 shader->declareFloat("uFogR");
316 shader->declareFloat("uFogG");
317 shader->declareFloat("uFogB");
318 shader->declareFloat("uFogDensity");
319 shader->declareFloat("uFlash");
320}
321} // namespace
322
324 if (impl_->built) return;
325 impl_->built = true;
326 impl_->gfx = gfx;
327 if (!gfx) return;
328
329 // ---- textures ----
330 std::vector<uint8_t> rainRgba, snowRgba;
331 genRainTexture(rainRgba);
332 genSnowTexture(snowRgba);
333 graphics::Texture *rainTex = gfx->newTexture(8, 32, rainRgba.data(), true, true);
334 graphics::Texture *snowTex = gfx->newTexture(16, 16, snowRgba.data(), true, true);
335
336 // ---- shaders (precompiled SPIR-V; runtime GLSL compile is not available on Windows) ----
337 std::vector<uint32_t> wv(weather_vert_spv, weather_vert_spv + weather_vert_spv_count);
338 std::vector<uint32_t> wf(weather_frag_spv, weather_frag_spv + weather_frag_spv_count);
339 std::vector<uint32_t> bv(bolt_vert_spv, bolt_vert_spv + bolt_vert_spv_count);
340 std::vector<uint32_t> bf(bolt_frag_spv, bolt_frag_spv + bolt_frag_spv_count);
341 graphics::Shader *weatherVert = gfx->newMeshShaderFromSpv(wv, wf);
342 graphics::Shader *boltShader = gfx->newMeshShaderFromSpv(bv, bf);
343 declareWeatherParams(weatherVert);
344 declareWeatherParams(boltShader);
345
346 // ---- rain ----
347 graphics::Mesh *rainMesh = buildFieldMesh(gfx, impl_->rng, kRainCount, 1.4f, 0.07f);
348 impl_->rain = graphics::Renderable3D::create();
349 impl_->rain->setMesh(rainMesh);
350 impl_->rain->setTexture(rainTex);
351 impl_->rainMat = gfx->newMaterial();
352 impl_->rainMat->setShadingModel("unlit");
353 impl_->rainMat->setReceiveLight(false);
354 impl_->rainMat->setReceiveShadow(false);
355 impl_->rainMat->setCastShadow(false);
356 impl_->rainMat->setTint(0.8f, 0.9f, 1.0f, 1.0f);
357 impl_->rainMat->setShader(weatherVert);
358 impl_->rain->setMaterial(impl_->rainMat);
359 impl_->rain->setVisible(false);
360
361 // ---- snow ----
362 graphics::Mesh *snowMesh = buildFieldMesh(gfx, impl_->rng, kSnowCount, 0.22f, 0.10f);
363 impl_->snow = graphics::Renderable3D::create();
364 impl_->snow->setMesh(snowMesh);
365 impl_->snow->setTexture(snowTex);
366 impl_->snowMat = gfx->newMaterial();
367 impl_->snowMat->setShadingModel("unlit");
368 impl_->snowMat->setReceiveLight(false);
369 impl_->snowMat->setReceiveShadow(false);
370 impl_->snowMat->setCastShadow(false);
371 impl_->snowMat->setTint(1.0f, 1.0f, 1.0f, 1.0f);
372 impl_->snowMat->setShader(weatherVert);
373 impl_->snow->setMaterial(impl_->snowMat);
374 impl_->snow->setVisible(false);
375
376 // ---- lightning bolts ----
377 for (int i = 0; i < kBoltCount; ++i) {
378 Pt top{impl_->rng.range(-4.f, 4.f), kBoxY, impl_->rng.range(-4.f, 4.f)};
379 Pt ground{impl_->rng.range(-3.f, 3.f), 0.f, impl_->rng.range(-3.f, 3.f)};
380 graphics::Mesh *m = buildBoltMesh(gfx, impl_->rng, top, ground);
381 graphics::Renderable3D *b = graphics::Renderable3D::create();
382 b->setMesh(m);
383 graphics::Material *mm = gfx->newMaterial();
384 mm->setShadingModel("unlit");
385 mm->setReceiveLight(false);
386 mm->setReceiveShadow(false);
387 mm->setCastShadow(false);
388 mm->setTint(1.0f, 1.0f, 1.0f, 1.0f);
389 mm->setShader(boltShader);
390 b->setMaterial(mm);
391 b->setVisible(false);
392 impl_->bolts.push_back(b);
393 impl_->boltMats.push_back(mm);
394 }
395
396 pushWeatherParams(impl_->rainMat, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
397 pushWeatherParams(impl_->snowMat, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
398}
399
400// ---------------------------------------------------------------------------
401// Public API
402// ---------------------------------------------------------------------------
403
404void Weather::setPreset(const std::string &name) {
405 for (int i = 0; i < kPresetCount; ++i) {
406 if (name == kPresetNames[i]) {
407 impl_->preset = i;
408 return;
409 }
410 }
411}
412
413std::string Weather::getPreset() const { return kPresetNames[impl_->preset]; }
414
416 impl_->intensity = v < 0.f ? 0.f : (v > 1.f ? 1.f : v);
417}
418float Weather::getIntensity() const { return impl_->intensity; }
419
420void Weather::setWindSpeed(float v) { impl_->windSpeed = v < 0.f ? 0.f : v; }
421float Weather::getWindSpeed() const { return impl_->windSpeed; }
422
423void Weather::setWindDirection(float deg) { impl_->windDirDeg = deg; }
424float Weather::getWindDirection() const { return impl_->windDirDeg; }
425
426void Weather::setLightningEnabled(bool on) { impl_->lightningEnabled = on; }
427bool Weather::isLightningEnabled() const { return impl_->lightningEnabled; }
428
430 if (!impl_->built || impl_->bolts.empty()) return;
431 impl_->activeBolt = impl_->rng.next() % int(impl_->bolts.size());
432 impl_->boltLife = 0.0f;
433 impl_->boltOnceFired = false;
434 impl_->flash = 1.0f;
435 impl_->flashTimer = 0.12f;
436 impl_->nextStrike = 3.0f + impl_->rng.unit() * 6.0f;
437}
438
439float Weather::getFlash() const { return impl_->flash; }
440
441void Weather::setSkyColor(float r, float g, float b) {
442 impl_->skyR = r; impl_->skyG = g; impl_->skyB = b;
443}
444float Weather::getSkyColorR() const { return impl_->skyR; }
445float Weather::getSkyColorG() const { return impl_->skyG; }
446float Weather::getSkyColorB() const { return impl_->skyB; }
447
448void Weather::setSunIntensity(float v) { impl_->sunIntensity = v < 0.f ? 0.f : v; }
449float Weather::getSunIntensity() const { return impl_->sunIntensity; }
450
451void Weather::setFogColor(float r, float g, float b) {
452 impl_->fogR = r; impl_->fogG = g; impl_->fogB = b;
453}
454float Weather::getFogColorR() const { return impl_->fogR; }
455float Weather::getFogColorG() const { return impl_->fogG; }
456float Weather::getFogColorB() const { return impl_->fogB; }
457
458void Weather::setFogDensity(float v) { impl_->fogDensity = v < 0.f ? 0.f : v; }
459float Weather::getFogDensity() const { return impl_->fogDensity; }
460
462 return 0.35f + (1.f - impl_->intensityCur) * 0.55f;
463}
464
465// ---------------------------------------------------------------------------
466// Update
467// ---------------------------------------------------------------------------
468
470 if (!impl_->built) init(gfx);
471 if (!impl_->gfx) return;
472 impl_->time += dt;
473
474 // Smooth intensity toward target.
475 const float target = impl_->intensity;
476 impl_->intensityCur += (target - impl_->intensityCur) * std::min(1.f, dt * 3.f);
477 if (std::fabs(target - impl_->intensityCur) < 0.002f) impl_->intensityCur = target;
478
479 // Wind vector in world space (dirDeg 0 -> +Z, 90 -> -X).
480 const float rad = impl_->windDirDeg * 0.0174532925f;
481 const float windX = -std::sin(rad) * impl_->windSpeed;
482 const float windZ = std::cos(rad) * impl_->windSpeed;
483
484 const float time = impl_->time;
485 const float fogR = impl_->fogR, fogG = impl_->fogG, fogB = impl_->fogB;
486 const float fogD = impl_->fogDensity;
487 const float intensity = impl_->intensityCur;
488
489 // Rain visible for drizzle/rain/storm.
490 const bool rainOn = impl_->preset >= 1 && impl_->preset <= 3;
491 impl_->rain->setVisible(rainOn && intensity > 0.01f);
492 if (rainOn) {
493 const float speed = 26.f;
494 pushWeatherParams(impl_->rainMat, time, windX, windZ, speed, 1.4f, 0.07f, intensity,
495 fogR, fogG, fogB, fogD, 0.f);
496 }
497
498 // Snow.
499 const bool snowOn = impl_->preset == 4;
500 impl_->snow->setVisible(snowOn && intensity > 0.01f);
501 if (snowOn) {
502 pushWeatherParams(impl_->snowMat, time, windX, windZ, 2.2f, 0.22f, 0.10f, intensity,
503 fogR, fogG, fogB, fogD, 0.f);
504 }
505
506 // Lightning during storm.
507 const bool storm = impl_->preset == 3;
508 if (storm && impl_->lightningEnabled) {
509 impl_->nextStrike -= dt;
510 if (impl_->nextStrike <= 0.f && impl_->activeBolt < 0) strike();
511 }
512
513 // Drive the active bolt's flash decay.
514 if (impl_->activeBolt >= 0) {
515 impl_->boltLife += dt;
516 impl_->flashTimer -= dt;
517 // Flicker: rapid on/off at the start, then decay.
518 float f;
519 if (impl_->boltLife < 0.05f) {
520 f = 1.f;
521 } else if (impl_->boltLife < 0.20f) {
522 // Fast flicker.
523 f = 0.25f + 0.75f * std::fabs(std::sin(impl_->boltLife * 120.f));
524 } else {
525 f = std::max(0.f, 1.f - (impl_->boltLife - 0.20f) / 0.15f);
526 }
527 impl_->flash = std::clamp(f, 0.f, 1.f);
528
529 const int bi = impl_->activeBolt;
530 impl_->bolts[bi]->setVisible(impl_->flash > 0.02f);
531 pushWeatherParams(impl_->boltMats[bi], time, windX, windZ, 0.f, 0.f, 0.f, 1.f, fogR, fogG,
532 fogB, fogD, impl_->flash);
533
534 if (impl_->boltLife > 0.35f) {
535 impl_->bolts[bi]->setVisible(false);
536 impl_->activeBolt = -1;
537 impl_->flash = 0.f;
538 }
539 } else {
540 impl_->flash *= std::max(0.f, 1.f - dt * 8.f);
541 }
542
543 // Push ambient/sky mood onto the graphics state each frame.
544 if (gfx) {
545 const float dark = 1.f - 0.65f * impl_->intensityCur;
546 gfx->setBackgroundColorRGBA(impl_->skyR * dark, impl_->skyG * dark,
547 impl_->skyB * dark, 1.f);
548 gfx->setDirectionalLight(-0.4f, 0.75f, 0.5f,
549 impl_->sunIntensity * (1.f - 0.6f * impl_->intensityCur) * 1.0f,
550 impl_->sunIntensity * (1.f - 0.6f * impl_->intensityCur) * 0.95f,
551 impl_->sunIntensity * (1.f - 0.6f * impl_->intensityCur) * 0.88f);
552 }
553}
554
555// ---------------------------------------------------------------------------
556// Script binding
557// ---------------------------------------------------------------------------
558
559void Weather::expose(ssq::Table &table) {
560 auto cls = table.addClass(name, Weather::create, false);
561 expose(cls);
562}
563
564void Weather::expose(ssq::Class &cls) {
565 cls.addFunc("getName", &Weather::getName);
566 cls.addFunc("init", &Weather::init);
567 cls.addFunc("update", &Weather::update);
568 cls.addFunc("setPreset", &Weather::setPreset);
569 cls.addFunc("getPreset", &Weather::getPreset);
570 cls.addFunc("setIntensity", &Weather::setIntensity);
571 cls.addFunc("getIntensity", &Weather::getIntensity);
572 cls.addFunc("setWindSpeed", &Weather::setWindSpeed);
573 cls.addFunc("getWindSpeed", &Weather::getWindSpeed);
574 cls.addFunc("setWindDirection", &Weather::setWindDirection);
575 cls.addFunc("getWindDirection", &Weather::getWindDirection);
576 cls.addFunc("setLightningEnabled", &Weather::setLightningEnabled);
577 cls.addFunc("isLightningEnabled", &Weather::isLightningEnabled);
578 cls.addFunc("strike", &Weather::strike);
579 cls.addFunc("getFlash", &Weather::getFlash);
580 cls.addFunc("setSkyColor", &Weather::setSkyColor);
581 cls.addFunc("getSkyColorR", &Weather::getSkyColorR);
582 cls.addFunc("getSkyColorG", &Weather::getSkyColorG);
583 cls.addFunc("getSkyColorB", &Weather::getSkyColorB);
584 cls.addFunc("setSunIntensity", &Weather::setSunIntensity);
585 cls.addFunc("getSunIntensity", &Weather::getSunIntensity);
586 cls.addFunc("setFogColor", &Weather::setFogColor);
587 cls.addFunc("getFogColorR", &Weather::getFogColorR);
588 cls.addFunc("getFogColorG", &Weather::getFogColorG);
589 cls.addFunc("getFogColorB", &Weather::getFogColorB);
590 cls.addFunc("setFogDensity", &Weather::setFogDensity);
591 cls.addFunc("getFogDensity", &Weather::getFogDensity);
592 cls.addFunc("getAmbientBrightness", &Weather::getAmbientBrightness);
593}
594
596
597} // namespace eve::weather
float cx
Definition CardTypes.cpp:31
float cy
Definition CardTypes.cpp:32
HSQOBJECT cls
Definition ECS.cpp:21
int y
Definition Grass.cpp:135
int z
Definition Grass.cpp:135
float u
Definition Grass.cpp:234
int x
Definition Grass.cpp:135
glm::vec3 n
Definition Grass.cpp:64
int h
int w
uint32_t a
uint32_t b
#define Module_IMPL(ModuleName, newExpr)
Definition Module.h:24
int width
int idx
float f
glm::vec4 p[6]
Shader * shader
const char * name
Definition RockMesh.cpp:21
int v
float m[16]
uint32_t s
Definition Weather.cpp:28
virtual std::string getName() const =0
virtual void setDirectionalLight(float dx, float dy, float dz, float r=1.f, float g=1.f, float b=1.f)
Definition Graphics.cpp:167
virtual Shader * newMeshShaderFromSpv(const std::vector< uint32_t > &vertSpv, const std::vector< uint32_t > &fragSpv)=0
Create a Mesh3D custom shader (MeshVertex + Frame UBO + albedo). Empty vert → default mesh3d....
virtual void setBackgroundColorRGBA(float r, float g, float b, float a=1.f)
Definition Graphics.cpp:867
virtual Texture * newTexture(int width, int height, const uint8_t *rgba, bool repeatU=false, bool repeatV=false)=0
Material * newMaterial()
Create a Material asset (shading model + textures + PBR knobs). Caller owns Material*; not tracked by...
Definition Graphics.cpp:171
Packages shading method + surface parameters into one attachable asset.
Definition Material.h:26
void setCastShadow(bool cast)
Definition Material.h:78
void setReceiveShadow(bool receive)
Definition Material.h:81
void setReceiveLight(bool receive)
Definition Material.h:75
void setShadingModel(const std::string &model)
"pbr" | "unlit" | "hair" | "custom" (unknown → pbr).
Definition Material.cpp:9
void setTint(float r, float g, float b, float a=1.f)
Definition Material.cpp:19
void setFloat(const std::string &name, float value)
Definition Material.cpp:56
void setShader(Shader *shader)
Optional Mesh3D / hair Shader. nullptr → built-in path for the shading model.
Definition Material.h:50
GPU mesh handle (+ optional CPU morph targets).
Definition Mesh.h:18
void setTexture(Texture *texture)
void setMaterial(Material *material)
Attach a Material that packages shading method + surface params.
Custom GPU program.
Definition Shader.h:30
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:17
Weather module — real-time precipitation / lightning / wind system.
Definition Weather.h:31
static const char *const kPresetNames[]
Definition Weather.h:46
void setSunIntensity(float v)
Definition Weather.cpp:448
float getFogColorB() const
Definition Weather.cpp:456
static const int kPresetCount
Definition Weather.h:47
float getFogDensity() const
Definition Weather.cpp:459
void setWindSpeed(float v)
Definition Weather.cpp:420
void init(graphics::Graphics *gfx)
Idempotent; builds meshes/shaders on first call.
Definition Weather.cpp:323
void setLightningEnabled(bool on)
Definition Weather.cpp:426
void setIntensity(float v)
Definition Weather.cpp:415
float getFogColorG() const
Definition Weather.cpp:455
void strike()
Force a bolt strike this frame (useful for manual testing).
Definition Weather.cpp:429
void setSkyColor(float r, float g, float b)
Definition Weather.cpp:441
float getWindDirection() const
Definition Weather.cpp:424
void setFogDensity(float v)
Definition Weather.cpp:458
std::string getPreset() const
Definition Weather.cpp:413
float getFogColorR() const
Definition Weather.cpp:454
float getSunIntensity() const
Definition Weather.cpp:449
float getSkyColorG() const
Definition Weather.cpp:445
float getSkyColorB() const
Definition Weather.cpp:446
void setPreset(const std::string &name)
Definition Weather.cpp:404
bool isLightningEnabled() const
Definition Weather.cpp:427
float getWindSpeed() const
Definition Weather.cpp:421
float getFlash() const
How bright the current flash is (0..1), sampled by the scene for a key light.
Definition Weather.cpp:439
float getAmbientBrightness() const
Ambient multiplier that the example should feed into camera.setAmbient().
Definition Weather.cpp:461
void update(float dt, graphics::Graphics *gfx)
Advance sim + push per-frame uniforms; must run before gfx.render3D().
Definition Weather.cpp:469
void setFogColor(float r, float g, float b)
Definition Weather.cpp:451
float getIntensity() const
Definition Weather.cpp:418
void setWindDirection(float degrees)
Wind direction in degrees; 0 = toward +Z, 90 = toward -X.
Definition Weather.cpp:423
float getSkyColorR() const
Definition Weather.cpp:444
graphics::Renderable3D * rain
Definition Weather.cpp:263
graphics::Renderable3D * snow
Definition Weather.cpp:264
graphics::Material * rainMat
Definition Weather.cpp:266
graphics::Graphics * gfx
Definition Weather.cpp:241
std::vector< graphics::Renderable3D * > bolts
Definition Weather.cpp:265
std::vector< graphics::Material * > boltMats
Definition Weather.cpp:268
graphics::Material * snowMat
Definition Weather.cpp:267