载入中...
搜索中...
未找到
LifeNetworkSolver.cpp
浏览该文件的文档.
2
4
5#include "common/Assert.h"
6
7#include <cmath>
8#include <vector>
9
10namespace eve::gpuagents {
11
12void LifeNetworkSolver::step(std::span<const AgentState> read, std::span<AgentState> write,
13 const EffectProfile& profile, const EnvironmentSnapshot& env, float dt) {
15 EV_PARAM_CHECK(read.size() == write.size());
16 const LifeNetworkProfile& p = profile.life;
17 EV_PARAM_CHECK(env.surface != nullptr);
18
19 SurfaceField& surface = *env.surface;
20 std::vector<glm::vec3> deposits;
21 deposits.reserve(read.size());
22
23 for (size_t i = 0; i < read.size(); ++i) {
24 const AgentState& in = read[i];
25 if (in.alive == 0) {
26 write[i] = in;
27 continue;
28 }
29
30 glm::vec3 heading = in.velocity;
31 if (glm::length(glm::vec2(heading.x, heading.z)) < 1e-4f) heading = glm::vec3(0.f, 0.f, 1.f);
32 heading.y = 0.f;
33 heading = glm::normalize(heading);
34
35 const float s = std::sin(p.sensorAngle);
36 const float c = std::cos(p.sensorAngle);
37 const glm::vec3 leftDir(heading.x * c + heading.z * s, 0.f, -heading.x * s + heading.z * c);
38 const glm::vec3 rightDir(heading.x * c - heading.z * s, 0.f, heading.x * s + heading.z * c);
39
40 const auto sense = [&](const glm::vec3& dir) {
41 const glm::vec3 sp = in.position + dir * p.sensorDistance;
42 const glm::vec4 life = surface.sampleLife(sp.x, sp.z);
43 const glm::vec3 n = surface.sampleNormal(sp.x, sp.z);
44 float score = life.r * p.trailFollow + life.g * p.nutrient - life.b * p.danger;
45 // Soft repulsion from saturated trails encourages exploration.
46 score -= life.r * life.r * p.repulsion * 0.25f;
47 if (n.y < p.minSurfaceNormalZ) score -= 10.f;
48 for (const auto& d : env.dangers) {
49 const float dist = glm::length(sp - d.position);
50 if (dist < d.radius) score -= detail::compactWeight(dist, d.radius) * d.strength * p.danger;
51 }
52 for (const auto& nMark : env.nutrients) {
53 const float dist = glm::length(sp - nMark.position);
54 if (dist < nMark.radius)
55 score += detail::compactWeight(dist, nMark.radius) * nMark.strength * p.nutrient;
56 }
57 return score;
58 };
59
60 const float scoreF = sense(heading);
61 const float scoreL = sense(leftDir);
62 const float scoreR = sense(rightDir);
63
64 glm::vec3 choose = heading;
65 if (scoreL > scoreF && scoreL >= scoreR) choose = leftDir;
66 else if (scoreR > scoreF && scoreR > scoreL)
67 choose = rightDir;
68
69 AgentState out = in;
70 out.velocity = choose * p.moveSpeed;
71 out.position = in.position + out.velocity * dt;
72 out.position = surface.project(out.position);
73 const glm::vec3 n = surface.sampleNormal(out.position.x, out.position.z);
74 if (n.y < p.minSurfaceNormalZ) {
75 // Slide back toward previous feasible point.
76 out.position = surface.project(in.position);
77 out.velocity = -choose * p.moveSpeed * 0.5f;
78 }
79 out.rotation = lookRotation(out.velocity, n);
80 out.age = in.age + dt;
81 out.customData[0] = surface.sampleLife(out.position.x, out.position.z).r;
82 out.alive = in.alive;
83 deposits.push_back(out.position);
84 write[i] = out;
85 }
86
87 surface.stepLife(dt, p.trailDecayRate, p.freshnessHalfLife, p.diffusionRate, deposits, p.depositStrength);
88}
89
90} // namespace eve::gpuagents
double score
Definition Agent.cpp:50
EVEngine assertion entry point, backed by zeroerr.
#define EV_PARAM_CHECK(cond,...)
Validate a function parameter / public API precondition.
Definition Assert.h:30
const std::string & s
glm::vec4 p[6]
glm::vec3 n
Definition Grass.cpp:63
std::int32_t c
float d
V3 heading
Definition TreeMesh.cpp:292
V3 dir
Definition TreeMesh.cpp:150
void step(std::span< const AgentState > read, std::span< AgentState > write, const EffectProfile &profile, const EnvironmentSnapshot &env, float dt) override
Step.
2.5D surface + life-field textures for Life Network.
glm::vec3 sampleNormal(float x, float z) const
Bilinear sample of surface normal.
glm::vec3 project(const glm::vec3 &p) const
Project a world point onto the surface (Y from height).
void stepLife(float dt, float decayRate, float halfLife, float diffusion, const std::vector< glm::vec3 > &deposits, float depositStrength)
Advance trail deposit / decay / diffusion / danger for one fixed step.
glm::vec4 sampleLife(float x, float z) const
Bilinear sample of life RGBA.
float compactWeight(float dist, float radius)
Compact-support radial weight w(q)=(1-q)^2 for q in [0,1).
Definition BoidsCommon.h:15
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 > nutrients
SurfaceField * surface
optional; Life Network writes trails here
std::vector< EnvironmentMarker > dangers
Life Network 2D surface-trail parameters.