载入中...
搜索中...
未找到
FishSolver.cpp
浏览该文件的文档.
2
4
5#include "common/Assert.h"
6
7namespace eve::gpuagents {
8
9void FishSolver::step(std::span<const AgentState> read, std::span<AgentState> write, const EffectProfile& profile,
10 const EnvironmentSnapshot& env, float dt) {
12 EV_PARAM_CHECK(read.size() == write.size());
13 const FishProfile& p = profile.fish;
14
15 for (size_t i = 0; i < read.size(); ++i) {
16 const AgentState& in = read[i];
17 if (in.alive == 0) {
18 write[i] = in;
19 continue;
20 }
21 glm::vec3 forward = in.velocity;
22 if (glm::length(forward) < 1e-4f) forward = glm::vec3(0.f, 0.f, 1.f);
23 else
24 forward = glm::normalize(forward);
25
26 const auto acc = detail::gatherNeighbors(read, static_cast<int>(i), forward, p.separationRadius,
27 p.cohesionRadius, p.alignmentRadius, p.perceptionFovDegrees,
28 p.maxNeighborSamples);
29
30 glm::vec3 force(0.f);
31 if (acc.sepWeightSum > 0.f) force += (acc.separation / acc.sepWeightSum) * p.separationWeight;
32 if (acc.cohWeightSum > 0.f) {
33 const glm::vec3 center = acc.cohesionPos / acc.cohWeightSum;
34 const glm::vec3 toC = center - in.position;
35 const float len = glm::length(toC);
36 if (len > 1e-4f) force += (toC / len) * p.cohesionWeight;
37 }
38 if (acc.aliWeightSum > 0.f) {
39 const glm::vec3 avgV = acc.alignmentVel / acc.aliWeightSum;
40 const glm::vec3 delta = avgV - in.velocity;
41 force += delta * p.alignmentWeight;
42 }
43
44 force += detail::markerForce(in.position, env.goals, true) * p.goalWeight;
45 force += detail::markerForce(in.position, env.dangers, false) * p.dangerWeight;
46 force += env.waterCurrent * p.currentWeight;
47
48 const float depthErr = (in.position.y - p.preferredDepth) / std::max(p.depthTolerance, 1e-3f);
49 force.y -= depthErr * p.depthWeight;
50
51 AgentState out;
52 detail::integrateBoid(out, in, force, dt, p.maxAcceleration, p.maxSpeed, p.maxHorizontalTurn,
53 p.maxVerticalTurn);
54 if (env.obstacles) {
55 env.obstacles->resolve(out.position, out.velocity, p.base.agentRadius, p.base.obstaclePredictTime);
57 }
58 write[i] = out;
59 }
60}
61
62} // namespace eve::gpuagents
EVEngine assertion entry point, backed by zeroerr.
#define EV_PARAM_CHECK(cond,...)
Validate a function parameter / public API precondition.
Definition Assert.h:30
glm::vec4 p[6]
void step(std::span< const AgentState > read, std::span< AgentState > write, const EffectProfile &profile, const EnvironmentSnapshot &env, float dt) override
Step.
Definition FishSolver.cpp:9
void resolve(glm::vec3 &position, glm::vec3 &velocity, float agentRadius, float predictTime) const
Push an agent out of obstacles and keep feasible tangential velocity.
glm::vec3 markerForce(const glm::vec3 &pos, const std::vector< EnvironmentMarker > &markers, bool attract)
Marker force.
Definition BoidsCommon.h:76
void integrateBoid(AgentState &out, const AgentState &in, glm::vec3 accel, float dt, float maxAccel, float maxSpeed, float maxHTurn, float maxVTurn)
Clamp acceleration then integrate semi-implicit Euler with turn-rate limits.
Definition BoidsCommon.h:90
NeighborAccum gatherNeighbors(std::span< const AgentState > agents, int selfIndex, const glm::vec3 &forward, float sepR, float cohR, float aliR, float fovDeg, int maxSamples)
Gather neighborhood forces with compact weights and FOV / sample caps.
Definition BoidsCommon.h:46
glm::quat lookRotation(const glm::vec3 &forward, const glm::vec3 &upHint=glm::vec3(0.f, 1.f, 0.f))
Builds a facing quaternion from a unit forward and approximate up.
Definition AgentState.h:36
Standardized per-agent simulation output shared by all effect kinds.
Definition AgentState.h:12
glm::quat rotation
wxyz storage (glm default).
Definition AgentState.h:15
std::uint32_t alive
0 = recycled / inactive slot.
Definition AgentState.h:18
Type-erased profile bundle owned by an EffectBackend.
Read-only environment semantics prepared by GpuAgentWorld each tick.
std::vector< EnvironmentMarker > goals
std::vector< EnvironmentMarker > dangers
3D Boids fish school parameters.