载入中...
搜索中...
未找到
ActionCameraBlock.cpp
浏览该文件的文档.
2
3#include <cmath>
4#include <limits>
5#include <string>
6#include <utility>
7
8namespace eve::action {
9namespace {
10
11Result<double> optionalNumber(const Value::Object& payload, std::string_view field, double fallback) {
12 const auto found = payload.find(std::string(field));
13 if (found == payload.end()) return Result<double>::success(fallback);
14 double value = 0.0;
15 if (const auto* integer = found->second.getIf<std::int64_t>())
16 value = static_cast<double>(*integer);
17 else if (const auto* decimal = found->second.getIf<double>())
18 value = *decimal;
19 else
21 Diagnostic::error(DiagnosticCode::InvalidArgument, "camera cue field must be numeric", std::string(field)));
22 if (!std::isfinite(value))
24 Diagnostic::error(DiagnosticCode::InvalidArgument, "camera cue field must be finite", std::string(field)));
26}
27
28} // namespace
29
31 ActionCameraCueBinding candidate;
32 const auto foundCue = payload.find("cue");
33 const auto* cue = foundCue == payload.end() ? nullptr : foundCue->second.getIf<std::string>();
34 if (!cue)
36 Diagnostic::error(DiagnosticCode::InvalidArgument, "camera cue must be text", "cue"));
37 auto parsedCue = LogicalId::parse(*cue);
38 if (!parsedCue)
40 Diagnostic::error(DiagnosticCode::InvalidArgument, "camera cue must be a LogicalId", "cue"));
41 candidate.cue = std::move(*parsedCue);
42
43 auto position = optionalNumber(payload, "positionAmplitude", candidate.positionAmplitude);
45 auto rotation = optionalNumber(payload, "rotationAmplitude", candidate.rotationAmplitude);
47 auto fov = optionalNumber(payload, "fovAmplitude", candidate.fovAmplitude);
48 if (!fov) return Result<ActionCameraCueBinding>::failure(fov.status());
49 auto duration = optionalNumber(payload, "durationSeconds", candidate.duration.seconds());
51 if (position.value() < 0.0)
53 DiagnosticCode::InvalidArgument, "camera position amplitude must be non-negative", "positionAmplitude"));
54 if (rotation.value() < 0.0)
56 DiagnosticCode::InvalidArgument, "camera rotation amplitude must be non-negative", "rotationAmplitude"));
57 const double maximumFloat = static_cast<double>(std::numeric_limits<float>::max());
58 if (position.value() > maximumFloat)
60 DiagnosticCode::InvalidArgument, "camera position amplitude exceeds runtime range", "positionAmplitude"));
61 if (rotation.value() > maximumFloat)
63 DiagnosticCode::InvalidArgument, "camera rotation amplitude exceeds runtime range", "rotationAmplitude"));
64 if (std::abs(fov.value()) > maximumFloat)
66 DiagnosticCode::InvalidArgument, "camera FOV amplitude exceeds runtime range", "fovAmplitude"));
67 if (duration.value() <= 0.0)
69 DiagnosticCode::InvalidArgument, "camera cue duration must be positive", "durationSeconds"));
70 if (duration.value() > maximumFloat)
72 DiagnosticCode::InvalidArgument, "camera cue duration exceeds runtime range", "durationSeconds"));
73 auto parsedDuration = Duration::fromSeconds(duration.value());
74 if (!parsedDuration) return Result<ActionCameraCueBinding>::failure(parsedDuration.status());
75 candidate.positionAmplitude = position.value();
76 candidate.rotationAmplitude = rotation.value();
77 candidate.fovAmplitude = fov.value();
78 candidate.duration = std::move(parsedDuration).takeValue();
79
80 if (const auto foundSeed = payload.find("seed"); foundSeed != payload.end()) {
81 const auto* seed = foundSeed->second.getIf<std::int64_t>();
82 if (!seed || *seed < 0 || static_cast<std::uint64_t>(*seed) > std::numeric_limits<std::uint32_t>::max())
84 DiagnosticCode::InvalidArgument, "camera cue seed must be an unsigned 32-bit integer", "seed"));
85 candidate.seed = static_cast<std::uint32_t>(*seed);
86 }
87 return Result<ActionCameraCueBinding>::success(std::move(candidate));
88}
89
90} // namespace eve::action
Typed camera-cue action block contract.
double value
Value::Object payload
std::array< float, 4 > rotation
std::array< float, 3 > position
bool found
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
static Result< Duration > fromSeconds(double seconds)
Convert finite seconds to the nearest nanosecond.
Definition Time.cpp:16
double seconds() const noexcept
Return this duration as seconds for legacy/presentation APIs.
Definition Time.cpp:28
static std::optional< LogicalId > parse(std::string_view text)
Parses a scoped logical name.
Definition Identity.cpp:36
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
std::map< std::string, Value > Object
Definition Value.h:34
Owning validated camera impulse shared by action runtime and camera targets.
double fovAmplitude
Additive vertical field-of-view impulse in degrees.
LogicalId cue
Stable project-defined cue identity used for target selection.
static Result< ActionCameraCueBinding > fromPayload(const Value::Object &payload)
Decode a camera cue transactionally.
double positionAmplitude
Positional shake amplitude in world units.
std::uint32_t seed
Stable deterministic noise seed.
Duration duration
Positive duration of the damped impulse.
double rotationAmplitude
Rotational shake amplitude in degrees.