载入中...
搜索中...
未找到
CrowdStep.cpp
浏览该文件的文档.
1#include "common/Profile.h"
3
4namespace eve::crowd {
5
7 EV_PROFILE_MODULE("crowd", "Crowd::advance");
8 if (!std::isfinite(dt) || dt < 0.f)
10 Diagnostic::error(DiagnosticCode::InvalidArgument, "Crowd dt must be finite and non-negative", "dt"));
11 StepReport report;
12 if (dt == 0.f || impl_->xs.empty()) return Result<StepReport>::success(report, Status::success(StatusCode::NoOp));
13
14 auto& d = *impl_;
15 d.avoidanceChecks = 0;
16 d.avoidanceTruncations = 0;
17 double maxStep = 1.0 / 60.0;
18 float travelScale = d.field.valid() ? d.field.getCellSize() : 0.f;
19 float maxSpeed = 0.f;
20 for (size_t i = 0; i < d.xs.size(); ++i) {
21 if (d.radii[i] > 0.f) travelScale = travelScale > 0.f ? std::min(travelScale, d.radii[i]) : d.radii[i];
22 maxSpeed = std::max(maxSpeed, d.maxSpeeds[i]);
23 }
24 if (travelScale > 0.f && maxSpeed > 0.f) maxStep = std::min(maxStep, 0.5 * double(travelScale) / double(maxSpeed));
25 // Float dt=1/60 rounds slightly upward. Do not create an extra substep for
26 // representation error at an otherwise exact boundary.
27 const double count = std::ceil(double(dt) / maxStep - 1e-6);
28 if (!std::isfinite(count) || count > 1024.0)
30 DiagnosticCode::PreconditionViolation, "Crowd step exceeds 1024 substeps; reduce dt or speed", "dt"));
31 report.substeps = std::max(1, static_cast<int>(count));
32 const float substep = dt / float(report.substeps);
33 for (int sub = 0; sub < report.substeps; ++sub) {
34 d.simTime += substep;
35 d.rebuildGrid();
36 d.stepAgents(substep);
37 d.resolveWalls();
38 if (d.resolveOverlaps) {
39 for (int pass = 0; pass < 12; ++pass) {
40 d.rebuildGrid();
41 const float penetration = d.resolveOverlapsPass();
42 d.resolveWalls();
43 if (penetration < 1e-4f) break;
44 }
45 }
46 }
47
48 d.rebuildGrid();
49 const float maxRadius = *std::max_element(d.radii.begin(), d.radii.end());
50 for (size_t i = 0; i < d.xs.size(); ++i) {
51 d.forEachNeighbor(d.xs[i], d.ys[i], d.radii[i] + maxRadius, [&](int neighbor) {
52 const size_t j = size_t(neighbor);
53 if (j <= i || !d.canInteract(i, j)) return;
54 const float depth = d.radii[i] + d.radii[j] - std::hypot(d.xs[j] - d.xs[i], d.ys[j] - d.ys[i]);
55 report.maxPenetration = std::max(report.maxPenetration, depth);
56 if (depth > 0.001f) ++report.unresolvedContacts;
57 });
58 if (d.field.valid()) {
59 float x = d.xs[i], y = d.ys[i];
60 d.field.resolvePenetration(x, y, d.radii[i]);
61 bool outside = false;
62 if (d.clampToField) {
63 outside = d.xs[i] - d.radii[i] < d.field.getOriginX() - 0.001f ||
64 d.ys[i] - d.radii[i] < d.field.getOriginY() - 0.001f ||
65 d.xs[i] + d.radii[i] >
66 d.field.getOriginX() + float(d.field.getWidth()) * d.field.getCellSize() + 0.001f ||
67 d.ys[i] + d.radii[i] >
68 d.field.getOriginY() + float(d.field.getHeight()) * d.field.getCellSize() + 0.001f;
69 }
70 if (outside || std::hypot(x - d.xs[i], y - d.ys[i]) > 0.001f) ++report.unresolvedWalls;
71 }
72 }
73 report.avoidanceChecks = d.avoidanceChecks;
74 report.avoidanceTruncations = d.avoidanceTruncations;
76}
77
78void Crowd::step(float dt) { advance(dt).expect("Crowd step rejected"); }
79
80} // namespace eve::crowd
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
#define EV_PROFILE_MODULE(module, name)
Profile the enclosing scope, tagged with a module for grouping.
Definition Profile.h:140
float d
std::uint32_t count
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
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
void step(float dt)
Compatibility-only stepping facade; delegates to advance and throws on rejected input....
Definition CrowdStep.cpp:78
Result< StepReport > advance(float dt)
Advance using bounded simultaneous integration and contact projection.
Definition CrowdStep.cpp:6
Owning observations of one completed advance; simulation-thread only.
Definition Crowd.h:38
int avoidanceTruncations
Agent/substep queries exceeding the configured neighbor limit.
Definition Crowd.h:40
int unresolvedWalls
Final agents violating terrain or field bounds.
Definition Crowd.h:43
std::int64_t avoidanceChecks
Candidate-neighbor predictions across all substeps.
Definition Crowd.h:39
int substeps
Number of bounded integration intervals consumed.
Definition Crowd.h:41