载入中...
搜索中...
未找到
SkyTimeline.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5
6namespace eve::daynight {
7namespace {
8bool inRange(double value, double low, double high) { return std::isfinite(value) && value >= low && value <= high; }
9bool validWeather(const SkyWeather& weather) {
10 return inRange(weather.cloudCoverage, 0, 10) && inRange(weather.fog, 0, 1) && inRange(weather.rain, 0, 1) &&
11 inRange(weather.snow, 0, 1) && inRange(weather.windXZ[0], -1000, 1000) &&
12 inRange(weather.windXZ[1], -1000, 1000);
13}
14Diagnostic invalid(const char* message) {
16}
17} // namespace
18
19SkyTimeline::SkyTimeline(const SkyClock& clock, const SkyWeather& weather)
20 : clock_(clock), from_(weather), to_(weather) {}
21
22Result<SkyTimeline> SkyTimeline::create(const SkyClock& clock, const SkyWeather& weather) {
23 if (!inRange(clock.initialHour, 0, 24) || clock.initialHour == 24 || !inRange(clock.hoursPerSecond, 0, 24) ||
24 !validWeather(weather))
25 return Result<SkyTimeline>::failure(invalid("Invalid initial sky clock or weather"));
26 return Result<SkyTimeline>::success(SkyTimeline(clock, weather));
27}
28
29Result<void> SkyTimeline::advance(Duration duration) {
30 if (duration.nanoseconds() < 0) return Result<void>::failure(invalid("Sky time step must be nonnegative"));
31 auto next = elapsed_.tryAdd(duration);
32 if (!next) return Result<void>::failure(next.status());
33 elapsed_ = std::move(next).takeValue();
34 return Result<void>::success();
35}
36
37Result<void> SkyTimeline::transitionTo(const SkyWeather& target, Duration duration) {
38 if (!validWeather(target) || duration.nanoseconds() < 0)
39 return Result<void>::failure(invalid("Invalid sky weather or transition duration"));
40 const auto current = frame();
41 from_ = current.weather;
42 to_ = target;
43 travelOrigin_ = current.cloudTravelXZ;
44 transitionStart_ = elapsed_;
45 transitionDuration_ = duration;
46 return Result<void>::success();
47}
48
49SkyFrame SkyTimeline::frame() const noexcept {
50 SkyFrame result;
51 result.elapsedSeconds = elapsed_.seconds();
52 // Reduce before scaling so long-running clocks retain sub-day precision.
53 result.hour = clock_.hoursPerSecond == 0
54 ? clock_.initialHour
55 : std::fmod(clock_.initialHour +
56 std::fmod(elapsed_.seconds(), 24 / clock_.hoursPerSecond) * clock_.hoursPerSecond,
57 24);
58 const double age = Duration::fromNanoseconds(elapsed_.nanoseconds() - transitionStart_.nanoseconds()).seconds();
59 const double duration = transitionDuration_.seconds();
60 const double ramp = std::min(age, duration);
61 const double fraction = duration > 0 ? ramp / duration : 1;
62 const auto mix = [fraction](double a, double b) { return std::lerp(a, b, fraction); };
63 result.weather.cloudCoverage = mix(from_.cloudCoverage, to_.cloudCoverage);
64 result.weather.fog = mix(from_.fog, to_.fog);
65 result.weather.rain = mix(from_.rain, to_.rain);
66 result.weather.snow = mix(from_.snow, to_.snow);
67 for (size_t axis = 0; axis < 2; ++axis) {
68 result.weather.windXZ[axis] = mix(from_.windXZ[axis], to_.windXZ[axis]);
69 // Integrate the linear ramp plus constant-speed tail analytically. A large
70 // frame crossing the transition endpoint must equal many smaller frames.
71 result.cloudTravelXZ[axis] = travelOrigin_[axis] +
72 ramp * (from_.windXZ[axis] + result.weather.windXZ[axis]) * .5 +
73 (age - ramp) * to_.windXZ[axis];
74 }
75 return result;
76}
77} // namespace eve::daynight
LogicalId target
double value
float duration
std::string message
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
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
Signed, fixed-resolution simulation duration in nanoseconds.
Definition Time.h:43
Move-only operation result carrying either a value or Status.
Definition Result.h:155
Owns one independent sky clock, weather transition and integrated cloud travel.
Definition SkyTimeline.h:42
eve::Diagnostic Diagnostic
Result< int > invalid(std::string message)
Invalid.
Runtime clock configuration, independent of the legacy DayNight module.
Definition SkyTimeline.h:19
Copied sky simulation state shared by main-view and reflection consumers.
Definition SkyTimeline.h:25
std::array< double, 2 > cloudTravelXZ
Definition SkyTimeline.h:29
Independent sky weather values; distances are metres and wind is metres/second.
Definition SkyTimeline.h:10
std::array< double, 2 > windXZ
Definition SkyTimeline.h:15