载入中...
搜索中...
未找到
SceneWind.cpp
浏览该文件的文档.
2
3#include "common/Diagnostic.h"
4
5#include <algorithm>
6#include <cmath>
7
8namespace eve::graphics::fog {
9namespace {
10
11[[nodiscard]] float approach(float current, float target, float maxDelta) noexcept {
12 const float delta = target - current;
13 if (std::fabs(delta) <= maxDelta) return target;
14 return current + std::copysign(maxDelta, delta);
15}
16
17[[nodiscard]] glm::vec3 approach3(const glm::vec3& current, const glm::vec3& target,
18 float maxDelta) noexcept {
19 return {approach(current.x, target.x, maxDelta), approach(current.y, target.y, maxDelta),
20 approach(current.z, target.z, maxDelta)};
21}
22
23} // namespace
24
25Result<void> SceneWind::setMainWind(const glm::vec3& metersPerSecond) {
26 if (!std::isfinite(metersPerSecond.x) || !std::isfinite(metersPerSecond.y) ||
27 !std::isfinite(metersPerSecond.z)) {
29 DiagnosticCode::InvalidArgument, "main wind must be finite", "mainWind", {},
30 "graphics.fog"));
31 }
32 targetMain_ = metersPerSecond;
33 return Result<void>::success();
34}
35
37 if (!std::isfinite(metersPerSecond) || metersPerSecond < 0.f) {
39 DiagnosticCode::InvalidArgument, "curl strength must be finite and >= 0", "curlStrength",
40 {}, "graphics.fog"));
41 }
42 targetCurl_ = metersPerSecond;
43 return Result<void>::success();
44}
45
47 if (!std::isfinite(frequency) || frequency <= 0.f) {
49 DiagnosticCode::InvalidArgument, "curl frequency must be finite and > 0", "curlFrequency",
50 {}, "graphics.fog"));
51 }
52 curlFrequency_ = frequency;
53 return Result<void>::success();
54}
55
57 if (!std::isfinite(scale) || scale < 0.f) {
59 DiagnosticCode::InvalidArgument, "curl time scale must be finite and >= 0",
60 "curlTimeScale", {}, "graphics.fog"));
61 }
62 curlTimeScale_ = scale;
63 return Result<void>::success();
64}
65
66Result<void> SceneWind::setResponseRate(float metersPerSecondPerSecond) {
67 if (!std::isfinite(metersPerSecondPerSecond) || metersPerSecondPerSecond <= 0.f) {
69 DiagnosticCode::InvalidArgument, "response rate must be finite and > 0", "responseRate",
70 {}, "graphics.fog"));
71 }
72 responseRate_ = metersPerSecondPerSecond;
73 return Result<void>::success();
74}
75
77 if (!std::isfinite(dt) || dt < 0.f) {
79 DiagnosticCode::InvalidArgument, "dt must be finite and >= 0", "dt", {}, "graphics.fog"));
80 }
81 const float maxDelta = responseRate_ * dt;
82 currentMain_ = approach3(currentMain_, targetMain_, maxDelta);
83 currentCurl_ = approach(currentCurl_, targetCurl_, maxDelta);
84 return Result<void>::success();
85}
86
87glm::vec3 SceneWind::sample(const glm::vec3& world, float timeSeconds) const noexcept {
88 const float t = timeSeconds * curlTimeScale_;
89 const float f = curlFrequency_;
90 // Analytic curl of a smooth potential → locally swirling, nearly div-free.
91 const float sx = std::sin(f * world.y + 0.7f * t);
92 const float sy = std::sin(f * world.z + 1.1f * t);
93 const float sz = std::sin(f * world.x + 0.5f * t);
94 const float cx = std::cos(f * world.z + 0.9f * t);
95 const float cy = std::cos(f * world.x + 0.3f * t);
96 const float cz = std::cos(f * world.y + 1.3f * t);
97 const glm::vec3 curl(currentCurl_ * (sy - cz), currentCurl_ * (sz - cx),
98 currentCurl_ * (sx - cy));
99 return currentMain_ + curl;
100}
101
102} // namespace eve::graphics::fog
LogicalId target
float cx
Definition CardTypes.cpp:33
float cy
Definition CardTypes.cpp:34
Stable, structured diagnostics shared by engine modules.
std::array< float, 3 > scale
float f
World3D * world
float t
double current
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Result< void > setCurlStrength(float metersPerSecond)
Target curl amplitude in m/s.
Definition SceneWind.cpp:36
Result< void > setMainWind(const glm::vec3 &metersPerSecond)
Target main wind in m/s (world space).
Definition SceneWind.cpp:25
Result< void > tick(float dt)
Advance the limited-response filters by dt seconds.
Definition SceneWind.cpp:76
Result< void > setResponseRate(float metersPerSecondPerSecond)
Max response rate for wind changes (m/s per second).
Definition SceneWind.cpp:66
glm::vec3 sample(const glm::vec3 &world, float timeSeconds) const noexcept
Sample combined wind at a world position and simulation time. Curl is divergence-free on average and ...
Definition SceneWind.cpp:87
Result< void > setCurlTimeScale(float scale)
Time scale for curl animation (dimensionless, >= 0).
Definition SceneWind.cpp:56
Result< void > setCurlFrequency(float frequency)
Curl field spatial frequency (1/m).
Definition SceneWind.cpp:46